Compare commits

...
Author SHA1 Message Date
vorotamoroz a6c93c358e Merge pull request #1117 from vrtmrz/fix/couchdb-remote-connection-ownership
Record CouchDB remote connection ownership
2026-08-18 19:41:37 +09:00
vorotamoroz d9df2a859f docs: record pending CouchDB robustness improvement 2026-08-18 09:46:44 +00:00
vorotamoroz b7c2512da6 chore: adopt Commonlib 0.1.16 2026-08-18 09:17:22 +00:00
vorotamoroz 97b0ec25c7 docs: record CouchDB remote connection ownership 2026-08-18 07:52:16 +00:00
vorotamoroz bc41355a74 Merge pull request #1115 from vrtmrz/1_0_15
Releasing 1.0.15
2026-08-16 00:28:55 +09:00
github-actions[bot] 3d69142a52 Releasing 1.0.15 2026-08-15 15:05:11 +00:00
vorotamoroz 2403a66441 Merge pull request #1114 from vrtmrz/release-notes/1.0.15
Add 1.0.15 release notes
2026-08-16 00:03:46 +09:00
vorotamoroz 54e20dede3 docs: add 1.0.15 release notes 2026-08-15 14:57:29 +00:00
vorotamoroz 277091c1e4 Merge pull request #1113 from vrtmrz/docs/clarify-couchdb-provisioning-credentials
Clarify CouchDB setup credentials
2026-08-15 23:50:29 +09:00
vorotamoroz e294747557 Clarify CouchDB setup credentials 2026-08-15 14:38:28 +00:00
vorotamoroz 3062d45dc5 Merge pull request #1106 from nimula/i18n/zh-tw-catalogue-coverage
i18n(zh-tw): complete the catalogue coverage
2026-08-15 23:08:40 +09:00
vorotamoroz 8e14bc35d2 Merge pull request #1112 from vrtmrz/chore/commonlib-0.1.15
Update Commonlib to 0.1.15
2026-08-15 22:43:14 +09:00
nimulaandClaude Sonnet 5 0a1e1f3625 i18n(zh-tw): polish translation naturalness and terminology consistency
- Unify 資料庫適配器 -> 資料庫轉接器 across 6 entries so the database
  adapter setting uses one term throughout the catalogue.
- Drop the calqued "透過⋯⋯來⋯⋯" construction in 3 entries (Testing-only
  conflict resolution, the P2P replicator description, and the
  duplicated garbage-collection cleanup description); the sentences
  read the same without the borrowed English "by X to Y" shape.
- Rename the Eden-chunk "Incubate" feature's label from 孵化 (hatch) to
  暫存 (temporarily store) across 7 entries, matching the wording
  already used in the toggle's own description and avoiding a
  half-metaphor/half-literal split within the same feature.
- Convert the ASCII ellipsis "..." to the full-width "⋯" in 22
  in-progress/loading strings, per Taiwanese typography convention;
  the English source keys (which legitimately end in "...") are
  untouched.
- Reword "Fetch database with previous behaviour" to avoid a 以前/以
  + 前一種 parsing ambiguity, matching the 先前的行為 wording already
  used by the sibling 保留先前的行為 entry.
- Drop the orphaned closing paren in errMaxDocumentSize/errMaxRequestSize,
  fixing a display defect inherited from the English source.
- Add 同步 to beforeLiveSync for clarity.

Regenerated messagesJson/zh-tw.json and combinedMessages.prod.ts via
`npm run i18n:bake`; no other locale's entries changed.

Verified with tsc-check, lint, lint:community, lint:community:tools,
svelte-check, build, check:compatibility, and test:unit (630 tests,
88 files) — all pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 15:18:35 +08:00
nimulaandClaude Opus 5 b939687cb3 i18n(zh-tw): complete the catalogue coverage
Continues the zh-tw work from commit 0f50f290, which only translated the
190 keys `$msg()` calls in `src/` resolved through the catalogue at the
time. This closes the remaining gap: 573 of 1450 keys (39.5%) to 1446 of
1450 (99.7%), matching es (99.9%) and comfortably ahead of every other
locale except it.

While re-scanning to find the next batch, the earlier "code-referenced"
count turned out to be wrong: the previous grep only matched single-line
`$msg("literal")` calls and missed multi-line calls and the `msg`, `_msg`,
and `translateMessage` aliases various Svelte components import (e.g.
`import { $msg as msg } from "@/common/translation"`). A corrected scan
found 624 referenced keys, not 309, of which 350 were still untranslated —
mostly the P2P Sync status panes and several SetupWizard dialogues. Since
this pass translates everything remaining regardless of reference status,
that gap closes as a side effect; it is called out here only because it
explains why some of the newly translated strings are already visible in
today's UI rather than being pure catalogue completeness.

- Translated by area: P2P Sync replicator panes and the `P2P.*` runtime
  messages; ConfigSync's plugin/snippet/theme comparison UI; the
  SetupWizard's remote-setup, rebuild/fetch, and outro dialogues (both the
  legacy flat-key strings and the newer `Ui.SetupWizard.*` Svelte
  component keys); the Svelte-based `Ui.Settings.*` settings panels
  (Maintenance, Patches, Hatch, Remote, Common, Selector, PowerUsers,
  CustomisationSync, Advanced, Setup, SyncSettings); Setting Doctor
  (`Doctor.*`); the remote-size warning flow (`moduleCheckRemoteSize.*`);
  the redflag3 fetch-method chooser (`RedFlag.*`); the remaining
  `moduleMigration.*`, `liveSyncReplicator.*`, `Replicator.*`, and
  `TweakMismatchResolve.*` entries; and the rest of the plain
  English-sentence keys, including the language-picker's native-script
  entries (added `lang-he: עברית`, matching how `lang-de`/`lang-ja`/etc.
  already show each language's own name rather than a Chinese gloss).
- Wording follows docs/terms.md and the register already established in
  this file: `Setup URI`, `Vault`, `chunk(s)`, `Peer`, `Peer-to-Peer`,
  `Hatch`, and `CouchDB` stay untranslated as proper nouns; `resolved`
  (device/database state) is consistently 已處理, matching the existing
  Scram-dialogue usage.
- `${...}` placeholders and `%{...}` keyword references are kept
  byte-identical to the English source, including the multi-paragraph
  `RedFlag.Fetch.Method.Desc` and `moduleCheckRemoteSize.msgDatabaseGrowing`
  callout blocks; verified programmatically against all 1446 zh-tw
  entries.
- 4 keys are still deliberately left untranslated, unchanged from the
  previous commit: `moduleMigration.docUri` and
  `obsidianLiveSyncSettingTab.linkTroubleshooting` are a URL and a doc
  path, `obsidianLiveSyncSettingTab.logServerConfigurationCheck`'s English
  value is the key name itself, and `moduleLiveSyncMain.logPluginVersion`
  is a version-number template.
- Regenerated `messagesJson/zh-tw.json` and `combinedMessages.prod.ts`
  through the documented `i18n:bake` pipeline; no other language's
  entries changed.

Verified with tsc-check, tsc-check:apps, lint, lint:community,
lint:community:tools, svelte-check, check:compatibility, and test:unit
(604 tests, 86 files) — all pass.

Not in scope, unchanged from the previous commit: the ~137 Commonlib-owned
setting labels/descriptions never reach any translator because
`getConfig()` call sites in SettingDialogue omit the `translate` argument;
German is staged in the catalogue but never imported by
`combinedMessages.dev.ts`; Hebrew keyword references are never expanded by
`expandKeywords()`. None of these are specific to zh-tw and none are
touched here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 15:18:35 +08:00
nimulaandClaude Opus 5 df8c79538e i18n(zh-tw): translate the keys the application actually renders
The zh-tw catalogue was the weakest of the ten supported locales at 380 of
1450 keys (26%), well behind zh (75%) and ja (57%). Users who select
繁體中文 saw English for most of the interface.

This does not attempt full parity. It closes the gap for the 190 keys that
`$msg()` calls in `src/` actually resolve through the catalogue (zh-tw had
no entry for any of them), plus the 7 `K.*` keyword fragments that
`expandKeywords()` substitutes into `%{...}` references at build time
(zh-tw had none of these either, so any zh-tw message referencing `%{Peer}`
etc. would have shown the raw token on screen — the same defect currently
affecting `he`).

- 186 of the 190 code-referenced keys are translated. The remaining 4 are
  left as-is because their English value is not translatable prose:
  `moduleMigration.docUri` and `obsidianLiveSyncSettingTab.linkTroubleshooting`
  are a URL and a doc path, `obsidianLiveSyncSettingTab.logServerConfigurationCheck`'s
  English value is the key name itself, and `moduleLiveSyncMain.logPluginVersion`
  is a version-number template.
- Two pre-existing entries are corrected for internal consistency: `Bucket
  Name` (儲存桶→儲存庫) and `Peer-to-Peer Synchronisation` (點對點同步→
  Peer-to-Peer 同步), the latter matching the other three occurrences of
  "Peer-to-Peer" already left untranslated in this same file.
- Wording follows docs/terms.md and the existing zh-tw register: `Setup
  URI`, `Vault`, `chunk(s)`, `Hatch`, and `Peer-to-Peer` stay untranslated
  as proper nouns, matching how the rest of the file already treats them.
- `${...}` placeholders and `%{...}` keyword references are kept
  byte-identical to the English source; verified programmatically against
  all 573 zh-tw entries, not just the new ones.
- Regenerated `messagesJson/zh-tw.json` and `combinedMessages.prod.ts`
  through the documented `i18n:bake` pipeline; no other language's entries
  changed.

Coverage: 380/1450 (26.2%) -> 573/1450 (39.5%).

Verified with tsc-check, tsc-check:apps, lint, lint:community,
lint:community:tools, svelte-check, check:compatibility, and test:unit
(604 tests, 86 files) — all pass.

Not in scope, left for follow-up: the ~137 Commonlib-owned setting
labels/descriptions never reach any translator because `getConfig()` call
sites in SettingDialogue omit the `translate` argument; German is staged
in the catalogue but never imported by `combinedMessages.dev.ts`; Hebrew
keyword references are never expanded by `expandKeywords()`. None of these
are specific to zh-tw and none are touched here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 15:18:35 +08:00
13 changed files with 4031 additions and 48 deletions
@@ -0,0 +1,329 @@
# Architectural Decision Record: CouchDB Remote Connection Ownership
## Status
Accepted. The first implementation is deliberately limited to the
abort-capable CouchDB connectivity preflight used by one-shot replication.
## Context
Commonlib opens a remote CouchDB database through `RemoteService.connect()`.
Before this decision, a successful call returned only a PouchDB handle and an
information snapshot:
```typescript
{
db: PouchDB.Database<EntryDoc>;
info: PouchDB.Core.DatabaseInfo;
}
```
The value did not state who must close the handle or how requests which outlive
the current operation are cancelled. Callers consequently accumulated their
own `try`/`finally` blocks and closing helpers. Commonlib PR 112 made finite
handle clean-up substantially safer, but closing a raw PouchDB handle still did
not define ownership of its outstanding HTTP work.
A remote PouchDB HTTP handle is not a dedicated socket. `db.close()` emits
PouchDB's normal `closed` event and closes the logical handle, but the HTTP
adapter does not establish that a pending browser fetch or response-body read
has stopped. `RemoteService.performFetch()` also records a physical request as
complete once response headers have arrived, while PouchDB may still be reading
and parsing the body. Neither the request counters nor raw `db.close()` can
therefore prove that the transport work has settled.
One-shot CouchDB replication performs the following work before it creates the
replication controller:
1. prepare the encryption security seed;
2. construct the remote PouchDB handle and read database information;
3. check and, where required, migrate the remote database version;
4. read and update compatibility Metadata, including the milestone document;
and
5. create the PouchDB replication operation.
The controller owned by `processSync()` begins only at step 5. A request which
never settles during steps 2 to 4 is outside that cancellation scope. The
shared one-shot result remains pending as well, so later triggers join the same
pending operation rather than beginning a fresh attempt.
Self-hosted LiveSync issue 1116 provides evidence of this failure shape. On one
Linux and Electron combination, a one-shot attempt remained pending while
writing the remote milestone document. Bypassing that write allowed the
attempt to reach later replication requests. A local real-Obsidian exercise
reproduced the preceding Fast Fetch state but not the indefinite write. The
evidence does not establish a milestone-specific defect, a CouchDB defect, a
browser connection-pool defect, or a lock cycle. It does establish that the
connectivity preflight lacks an owner which can terminate its abort-capable
transport work.
No code-level circular wait has been identified. `shareRunningResult()` shares
a logical promise, the remote-activity counters observe work, and the global
replication concurrency controller is entered only after the preflight. Adding
a semaphore or another connection lock would let a stalled request retain the
permit; it would not make that request settle.
## Decision
### Extend the existing connection result
Commonlib will define the owned connection as the existing flat result with one
additional operation:
```typescript
interface RemoteConnectionOpenOptions {
readonly signal?: AbortSignal;
readonly allowNativeFallback?: boolean;
}
interface OwnedCouchDBConnection<T extends object> {
readonly db: PouchDB.Database<T>;
readonly info: PouchDB.Core.DatabaseInfo;
close(): Promise<void>;
}
interface CouchDBReplicationConnection extends OwnedCouchDBConnection<EntryDoc> {
readonly syncOptionBase: PouchDB.Replication.SyncOptions;
readonly syncOption: PouchDB.Replication.SyncOptions;
}
```
`RemoteService.connect()` remains the entry point. It returns
`OwnedCouchDBConnection` directly; there is no nested resource wrapper, separate
lease API, public connection signal, or public `abort()` operation. The
connection and checked replication types are owned and documented by
Commonlib. Compatibility checks enrich the same connection with replication
options instead of creating another lifetime object.
The following properties are part of the contract:
- `close()` is idempotent;
- `close()` first cancels abort-capable requests scoped to the connection, then
calls PouchDB's ordinary `db.close()`;
- PouchDB retains its normal `closed` event behaviour;
- the optional input signal cancels the same internal request scope;
- skipping the information request retains the established placeholder in
`info` for source and behaviour compatibility;
- a close failure is reported diagnostically but does not replace the primary
replication result; and
- ownership of the connection does not imply ownership of a dedicated physical
HTTP socket.
The public connection does not expose its internal signal because no caller
needs to make a second shutdown decision. Owners either cancel through the
input signal or finish through `close()`. This leaves one operation responsible
for final clean-up.
Replacing the existing error-string union with a typed connection-failure
result remains desirable, but it is outside this change. Mixing that migration
into the first implementation would enlarge the consumer and user-message
surface without improving cancellation.
### Bind cancellation at the custom fetch boundary
`RemoteService.connect()` creates its internal request scope before PouchDB is
constructed, so the initial `db.info()` request is covered. The custom PouchDB
fetch implementation combines, without replacing, both applicable signals:
- the signal supplied by PouchDB for the individual request; and
- the signal for the owned connection, which follows its optional owner signal.
The combined signal remains applicable while the response body is consumed.
Receiving response headers is not the end of cancellation ownership.
Cancellation is not a CORS failure. If the connection scope has been aborted,
the request must not enter the diagnostic fallback from the web-compatible
fetch path to the native request API. A bounded owner can also disable that
fallback explicitly.
The web-compatible fetch path honours `AbortSignal`. Obsidian's current native
`requestUrl` adapter does not expose physical cancellation through
`RequestInit.signal`. The implementation must not use `Promise.race()` to
declare a native remote write cancelled while it may still complete. A bounded
guarantee therefore applies only where the selected request path remains
abort-capable.
### Transfer the same connection between owners
At every point, exactly one operation is responsible for calling `close()`:
1. `RemoteService.connect()` owns the connection until it returns successfully;
2. the connectivity preflight owns it while checking version and compatibility;
3. a successful preflight transfers the same connection to the one-shot or
continuous replication operation; and
4. the final replication owner closes it after replication settles or is
terminated.
A failed factory or preflight closes the connection in its own failure path. A
successful transfer clears the former owner's deadline before replication
continues. Borrowing `connection.db` does not transfer close responsibility.
`shareRunningResult()` owns no connection. It may share the result of an
operation which owns one, but that operation must settle and close the
connection before the shared entry can be released for a later attempt.
## Limited Introduction
The first bounded consumer is the CouchDB connectivity preflight reached from
one-shot replication. Its boundary includes:
- PouchDB construction and the initial `db.info()` request;
- the database-version check and migration negotiation; and
- compatibility and milestone reads and writes before replication starts.
The preflight receives an internal 60-second wall-clock deadline. This is a
last-resort safety fuse for an owner which would otherwise remain pending
indefinitely. It is not the expected completion time, a service-level target, a
per-request inactivity timeout, a user setting, a limit on replication
duration, or the `useTimeouts` changes-feed setting. Tests inject a shorter
deadline.
When that deadline expires on the web-compatible path:
1. the owner signal aborts the connection's request scope;
2. the preflight closes the connection;
3. no PouchDB replication operation is created;
4. the shared one-shot result settles as failed; and
5. a later trigger may create a fresh connection and attempt.
On success, the deadline is cleared before the connection is transferred to
replication, so an old timer cannot interrupt a healthy long-running transfer.
The explicitly selected native Request API retains its previous unbounded
behaviour because its host adapter cannot honour transport cancellation. The
security-seed preparation which precedes the shared one-shot operation is also
outside this first boundary. Fast Fetch, setup probes, maintenance commands,
status inspection, and other direct CouchDB consumers retain their existing
deadline and retry policies. They receive the additive `close()` contract but
are not silently given this one-shot deadline.
The first implementation does not add automatic retry. Retrying before the old
request is known to be cancelled could duplicate remote writes or consume more
connections without changing the failing condition.
## Ownership
The legacy `_ensureConnection()` method retains its raw PouchDB return type for
source compatibility. New Commonlib paths use an internal owned-connection
helper and do not discard the lifecycle object.
Commonlib owns:
- `OwnedCouchDBConnection`, `RemoteConnectionOpenOptions`, and
`CouchDBReplicationConnection`;
- composition of PouchDB request and connection cancellation signals;
- the PouchDB custom-fetch integration;
- idempotent connection close behaviour;
- ownership transfer within the CouchDB replicator; and
- timeout classification at the connectivity-preflight boundary.
Self-hosted LiveSync owns:
- the concrete Obsidian fetch adapters and their declared capabilities;
- user-facing logs or notices for a timed-out attempt;
- integration of an immutable Commonlib release; and
- real-Obsidian validation of the affected consumer path.
No host may claim physical cancellation unless its injected fetch
implementation honours the supplied signal.
## Non-Goals
This decision does not:
- identify the exact environmental cause reported in issue 1116;
- guarantee that a one-shot attempt succeeds;
- special-case the milestone document or its URL;
- impose a global connection limit or connection semaphore;
- add an automatic retry, fallback, or remote reconciliation policy;
- apply a deadline to ordinary replication, continuous changes feeds, Fast
Fetch, rebuilds, or bulk transfers;
- change CouchDB documents, checkpoints, encryption, the security seed, or
compatibility Metadata;
- make `close()` equivalent to closing a browser socket;
- detach a potentially mutating native request and report it as cancelled; or
- migrate every direct PouchDB borrower to the one-shot deadline policy.
## Alternatives Rejected
### Time out only the milestone write
The observed write is where one report stopped, not an established ownership
boundary. Another environment could stop at `db.info()`, version Metadata,
response-body parsing, or an adjacent compatibility request.
### Race the preflight without cancelling its transport
This would release `shareRunningResult()` while the old request remained able
to complete. It is especially unsafe for a remote `PUT`, because a later
attempt could begin after the first had been reported as failed.
### Add a global semaphore or lower the connection count
No connection-limit failure has been demonstrated. A stalled owner would
retain its permit indefinitely and turn an unexplained request into an explicit
queue deadlock.
### Add a separate lease wrapper
A nested `{ connection: { db, close }, info }` result would make ownership
visible, but it would duplicate the existing connection shape, force callers
through another projection, and expose lifetime operations which have no
consumer. Adding `close()` to the existing value preserves source compatibility
and keeps the PouchDB handle, information snapshot, and lifetime together.
### Share one global remote PouchDB handle
A singleton would couple setup, maintenance, one-shot, and continuous
lifecycles, make credential and setting changes harder to isolate, and turn one
stalled request into a process-wide resource.
## Verification
The regression tests were changed before the implementation. Against the old
flat result they demonstrated that:
- an owner signal left an in-flight request pending;
- the result had no `close()` operation capable of interrupting a body read;
- a bounded web-compatible request could enter the native fallback; and
- the one-shot path still depended on the discarded nested connection API.
After the change, focused Commonlib tests verify that:
- an owner signal settles a pending request;
- `close()` interrupts a response body read before closing PouchDB;
- repeated `close()` calls close the handle once;
- an aborted or bounded request does not enter the non-abortable native adapter;
- deadline expiry closes the same flat connection and releases the shared
one-shot attempt;
- a later invocation begins after that release;
- a successful preflight clears its deadline and transfers ownership; and
- close failures are logged without replacing timeout or replication results.
Type checking and package-boundary checks verify the Commonlib-owned
declarations and compatibility export. Self-hosted LiveSync must then validate
the exact packed Commonlib artefact with its focused consumer tests and an
ordinary real-Obsidian and CouchDB smoke test. The reporter's environment
remains the validation boundary for the original platform-specific symptom.
## Consequences
- A successful remote connection has one explicit close operation without a
parallel lease abstraction.
- Existing `{ db, info }` consumers remain source-compatible and may adopt
`close()` without changing their projections.
- One-shot connectivity can become a bounded failure on an abort-capable
transport instead of retaining the shared operation indefinitely.
- Native `requestUrl` cancellation remains an acknowledged gap rather than a
falsely satisfied contract.
- Other finite consumers can adopt owner signals and explicit `close()` one at
a time, with tests for their own side effects and retry policies.
## References
- [Bounded Remote Activity](2026_07_bounded_remote_activity.md)
- [Fast Fetch Persistence and Completion Semantics](2026_08_fast_fetch_persistence_and_completion.md)
- Commonlib PR 112, which closes finite remote PouchDB handles after their
logical owners settle
- Self-hosted LiveSync issue 1116, which reports a one-shot compatibility write
remaining pending on one Linux and Electron environment
+9 -4
View File
@@ -118,10 +118,12 @@ Please refer to the [official document](https://docs.couchdb.org/en/stable/insta
Deno 2 is required. Export the CouchDB connection and database details, then run the provisioning wrapper:
The `username` and `password` in this step are CouchDB administrator credentials. For Docker or Docker Compose, use the same values supplied as `COUCHDB_USER` and `COUCHDB_PASSWORD`. For a direct installation, use the administrator configured during CouchDB setup. The wrapper does not create a separate non-administrator synchronisation account.
```
export hostname=http://localhost:5984
export username=<INSERT USERNAME HERE>
export password=<INSERT PASSWORD HERE>
export username=<INSERT COUCHDB ADMINISTRATOR USERNAME HERE>
export password=<INSERT COUCHDB ADMINISTRATOR PASSWORD HERE>
export database=obsidiannotes
curl -s https://raw.githubusercontent.com/vrtmrz/obsidian-livesync/main/utils/couchdb/couchdb-init.sh | bash
```
@@ -135,7 +137,7 @@ The wrapper runs the exact registry-pinned Commonlib consumer. When `database` i
If you are using Docker Compose and the above command does not work or displays `ERROR: Hostname missing`, you can try running the following command, replacing the placeholders with your own values:
```
curl -s https://raw.githubusercontent.com/vrtmrz/obsidian-livesync/main/utils/couchdb/couchdb-init.sh | hostname=http://<YOUR SERVER IP>:5984 username=<INSERT USERNAME HERE> password=<INSERT PASSWORD HERE> database=obsidiannotes bash
curl -s https://raw.githubusercontent.com/vrtmrz/obsidian-livesync/main/utils/couchdb/couchdb-init.sh | hostname=http://<YOUR SERVER IP>:5984 username=<INSERT COUCHDB ADMINISTRATOR USERNAME HERE> password=<INSERT COUCHDB ADMINISTRATOR PASSWORD HERE> database=obsidiannotes bash
```
## 3. Expose CouchDB to the Internet
@@ -170,10 +172,13 @@ Now `https://tiles-photograph-routine-groundwater.trycloudflare.com` is our serv
> A generated Setup URI is the recommended path because it carries the current defaults for a new Vault and the selected remote profile. If a Setup URI cannot be generated, follow [Configure CouchDB manually on the first device](./quick_setup.md#configure-couchdb-manually-on-the-first-device), then generate a new Setup URI from that working device for every additional device.
### 1. Generate the setup URI on a desktop device or server
The `username` and `password` here are the credentials which Self-hosted LiveSync will store for routine access to this database. They may be the administrator credentials from step 2. If you have separately configured a CouchDB account with the required access to this database, use that account instead. Neither the provisioning wrapper nor the Setup URI generator creates that separate account.
```bash
export hostname=https://tiles-photograph-routine-groundwater.trycloudflare.com
export database=obsidiannotes
export username=johndoe
export username=<INSERT COUCHDB USERNAME FOR LIVESYNC>
export password=<INSERT THE COUCHDB PASSWORD>
export passphrase=<INSERT A STRONG VAULT ENCRYPTION PASSPHRASE>
export uri_passphrase=<INSERT A SEPARATE SETUP URI PASSPHRASE> # Optional
+1 -1
View File
@@ -1,7 +1,7 @@
{
"id": "obsidian-livesync",
"name": "Self-hosted LiveSync",
"version": "1.0.14",
"version": "1.0.15",
"minAppVersion": "1.7.2",
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"author": "vorotamoroz",
+9 -9
View File
@@ -1,12 +1,12 @@
{
"name": "obsidian-livesync",
"version": "1.0.14",
"version": "1.0.15",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "obsidian-livesync",
"version": "1.0.14",
"version": "1.0.15",
"license": "MIT",
"workspaces": [
"src/apps/cli",
@@ -23,7 +23,7 @@
"@smithy/types": "^4.14.3",
"@smithy/util-retry": "^4.4.5",
"@vrtmrz/browser-ui-kit": "0.1.0",
"@vrtmrz/livesync-commonlib": "0.1.15",
"@vrtmrz/livesync-commonlib": "0.1.16",
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
"@vrtmrz/ui-interactions": "0.1.2",
"diff-match-patch": "^1.0.5",
@@ -4771,9 +4771,9 @@
}
},
"node_modules/@vrtmrz/livesync-commonlib": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.15.tgz",
"integrity": "sha512-uQxxzOdzu0MVcS6g20AxNLNj933Q3N5j/gZ2o6sem36vlsXQPKnsjGjTzrYcYAXNJ9mkR82EvC8qmKnOZvjEPg==",
"version": "0.1.16",
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.16.tgz",
"integrity": "sha512-vQlhLP2Qvf72zc/FedJQgOy/+Ri5zWuX+WKSD9fGaSWkBtX+nWkHx/9fgGdwkNEgighd4eCREVXfPvjcJKWX4w==",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-s3": "^3.808.0",
@@ -15923,7 +15923,7 @@
},
"src/apps/cli": {
"name": "self-hosted-livesync-cli",
"version": "1.0.14-cli",
"version": "1.0.15-cli",
"dependencies": {
"chokidar": "^4.0.0",
"minimatch": "^10.2.5",
@@ -15948,7 +15948,7 @@
},
"src/apps/webapp": {
"name": "livesync-webapp",
"version": "1.0.14-webapp",
"version": "1.0.15-webapp",
"dependencies": {
"octagonal-wheels": "^0.1.53"
},
@@ -15960,7 +15960,7 @@
}
},
"src/apps/webpeer": {
"version": "1.0.14-webpeer",
"version": "1.0.15-webpeer",
"dependencies": {
"octagonal-wheels": "^0.1.53"
},
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "obsidian-livesync",
"version": "1.0.14",
"version": "1.0.15",
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"main": "main.js",
"type": "module",
@@ -177,7 +177,7 @@
"@smithy/types": "^4.14.3",
"@smithy/util-retry": "^4.4.5",
"@vrtmrz/browser-ui-kit": "0.1.0",
"@vrtmrz/livesync-commonlib": "0.1.15",
"@vrtmrz/livesync-commonlib": "0.1.16",
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
"@vrtmrz/ui-interactions": "0.1.2",
"diff-match-patch": "^1.0.5",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "self-hosted-livesync-cli",
"private": true,
"version": "1.0.14-cli",
"version": "1.0.15-cli",
"main": "dist/index.cjs",
"type": "module",
"scripts": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "livesync-webapp",
"private": true,
"version": "1.0.14-webapp",
"version": "1.0.15-webapp",
"type": "module",
"description": "Browser-based Self-hosted LiveSync using FileSystem API",
"scripts": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "webpeer",
"private": true,
"version": "1.0.14-webpeer",
"version": "1.0.15-webpeer",
"type": "module",
"scripts": {
"dev": "vite",
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+23
View File
@@ -12,6 +12,29 @@ Earlier releases remain available in the 1.0 release history, the 1.0 preview hi
## Unreleased
### Synchronisation and storage
#### Improved
- One-shot CouchDB synchronisation now releases stalled web-compatible connection checks before replication starts, so a later synchronisation can make a fresh attempt (Commonlib 0.1.16).
- The 60-second safeguard applies only to pre-replication checks. It does not limit ordinary synchronisation, and the **Use Internal API** path is unchanged.
## 1.0.15
15th August, 2026
### Synchronisation and storage
#### Improved
- Start-up offline scanning is now faster, especially for larger Vaults using path obfuscation (Commonlib 0.1.15).
### Interface and translation
#### Improved
- The Traditional Chinese translation catalogue has been completed and polished for broader coverage and more natural, consistent terminology (PR #1106). Thank you to @nimula for the contribution!
## 1.0.14
14th August, 2026
+2 -1
View File
@@ -26,5 +26,6 @@
"1.0.11": "1.7.2",
"1.0.12": "1.7.2",
"1.0.13": "1.7.2",
"1.0.14": "1.7.2"
"1.0.14": "1.7.2",
"1.0.15": "1.7.2"
}