mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-09 09:17:45 +03:00
Compare commits
19 Commits
1.0.7
...
1.0.10-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b65deede79 | ||
|
|
9203bdd40e | ||
|
|
fcd30d07be | ||
|
|
cfb75a05db | ||
|
|
5b19f4415d | ||
|
|
047429033f | ||
|
|
9765569bb6 | ||
|
|
c5835a9da6 | ||
|
|
8311060f77 | ||
|
|
13d9624407 | ||
|
|
76560e3bf2 | ||
|
|
1e190d042c | ||
|
|
40215032dd | ||
|
|
fd9a9175dd | ||
|
|
1dfdb72fbd | ||
|
|
23d9fa360d | ||
|
|
070b63c952 | ||
|
|
d37af53858 | ||
|
|
cf5181bb28 |
11
.github/ISSUE_TEMPLATE/issue-report.md
vendored
11
.github/ISSUE_TEMPLATE/issue-report.md
vendored
@@ -8,7 +8,7 @@ assignees: ''
|
||||
---
|
||||
|
||||
Thank you for taking the time to report this issue!
|
||||
Before filling in this form, please read: [How to report an issue](../docs/to_issue_reporting.md).
|
||||
Before filling in this form, please read [How to report an issue](https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/to_issue_reporting.md).
|
||||
|
||||
Issues with sufficient information will be prioritised.
|
||||
|
||||
@@ -49,13 +49,14 @@ To get it: open the command palette → "Show debug info".
|
||||
</details>
|
||||
|
||||
### LiveSync version
|
||||
The hatch report (below) includes version information. If you cannot provide the report, please fill in the version here.
|
||||
The full LiveSync report below includes version information. If you cannot provide the report, please fill in the version here.
|
||||
|
||||
- Self-hosted LiveSync version: <!-- e.g. 0.23.0 — find it in Obsidian Settings → Community Plugins -->
|
||||
- Self-hosted LiveSync version: <!-- Find it in Obsidian Settings → Community plugins. -->
|
||||
|
||||
### Report and Logs from LiveSync
|
||||
Perform a `Generate full report for opening the issue with debug info` command and provide the generated report. This contains detailed information and recent 1000 log lines, which is very helpful for debugging. **PLEASE AMEND THE REPORT TO REMOVE ANY SENSITIVE INFORMATION BEFORE PASTING.**
|
||||
If too large to paste here, upload to [Gist](https://gist.github.com/) and share the link.
|
||||
Run `Generate full report for opening the issue with debug info` and provide the generated report. It contains detailed information and up to 1,000 recent log lines. Review the complete output, and remove credentials, private remote details, Vault names, file paths, file contents, and other private information before sharing it.
|
||||
|
||||
If the report is too large to paste here, upload the redacted report to [Gist](https://gist.github.com/) and share the link.
|
||||
|
||||
<details>
|
||||
<summary>Report and Logs (primary)</summary>
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
const id = params.get('id');
|
||||
const total = parseInt(params.get('n') || '0');
|
||||
const index = parseInt(params.get('i') || '-1');
|
||||
const data = params.get('d');
|
||||
// Keep the chunk percent-encoded so URI delimiters remain part of the settings payload.
|
||||
const data = hash.match(/(?:^|&)d=([^&]*)/)?.[1];
|
||||
|
||||
const app = document.getElementById('app');
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@ initialisation workflow relies:
|
||||
- every result from a batch write is checked;
|
||||
- a checkpoint represents the last contiguous remote sequence which is durable
|
||||
in the local database; and
|
||||
- successful completion means that the captured remote target has been reached,
|
||||
rather than that an estimated number of documents has been received.
|
||||
- successful completion requires CouchDB to terminate every finite changes page,
|
||||
every returned row to be durable, and a subsequent normal probe to report no
|
||||
available rows.
|
||||
|
||||
The existing implementation combines line parsing, decryption, persistence, and
|
||||
completion checks within one broad error handler. A decryption or persistence
|
||||
@@ -30,35 +31,89 @@ cases the stream may continue, advance its checkpoint incorrectly, or wait
|
||||
indefinitely for a completion condition which the failed row would have
|
||||
satisfied.
|
||||
|
||||
Fast Fetch also estimates the number of documents from the changes feed's
|
||||
`pending` value. That value is useful for progress reporting, but it is not an
|
||||
authoritative completion boundary. The CouchDB sequence token is opaque and must
|
||||
be handled using CouchDB's sequence semantics, without numeric-prefix comparison
|
||||
or inferred row counts. On clustered CouchDB, database information and the
|
||||
changes feed may encode the same position with different opaque tokens, so an
|
||||
`update_seq` from database information must not be compared directly with a
|
||||
changes-feed row.
|
||||
Fast Fetch also reads the normal changes feed before opening each continuous
|
||||
page. A normal response's `pending` value counts items which remain after the
|
||||
response's `results`, so `pending` alone is not the available workload. With a
|
||||
one-row probe, the page can contain `results.length + pending` rows.
|
||||
|
||||
The documented `limit=0` behaviour cannot be used as a portable zero-payload
|
||||
probe. CouchDB's API documentation says that `limit=0` has the same effect as
|
||||
`limit=1`, while CouchDB 3.5.0 with a two-shard database was observed to return
|
||||
no result rows and leave the complete count in `pending`. Fast Fetch therefore
|
||||
uses an explicit one-row normal probe and includes no document bodies.
|
||||
|
||||
Finite continuous-feed completion differs across supported CouchDB releases.
|
||||
CouchDB 3.5.0 was observed to close a heartbeat-enabled feed with a
|
||||
`{ "last_seq": ... }` line when its finite `limit` is met. CouchDB 3.2 instead
|
||||
continues to wait for database updates after the limit has been consumed. With
|
||||
a heartbeat configured, each wait emits another heartbeat and the page can
|
||||
remain open indefinitely, even after every requested row has arrived.
|
||||
|
||||
On CouchDB 3.2, an explicit `timeout` without a heartbeat has different
|
||||
semantics from a total request deadline. Shard-result waits may emit blank
|
||||
keep-alive lines and continue processing. Once the currently available changes
|
||||
have been exhausted and the feed is waiting for another database update, the
|
||||
timeout stops that wait and returns the feed-level `last_seq`. The timeout can
|
||||
therefore terminate a finite page without limiting the duration of an active
|
||||
page transfer.
|
||||
|
||||
The CouchDB sequence token is opaque and must be handled using CouchDB's
|
||||
sequence semantics, without parsing, ordering, or comparison. On clustered
|
||||
CouchDB, a changes row and the feed-level `last_seq` may encode related
|
||||
positions with different opaque tokens. Separate requests are also not one
|
||||
locked snapshot: their rows may be partially ordered, and replica failover may
|
||||
repeat changes. Fast Fetch must therefore be idempotent and must use each
|
||||
terminal `last_seq` only by returning it to CouchDB as the next `since` value.
|
||||
|
||||
## Decision
|
||||
|
||||
### Remote snapshot and completion
|
||||
### Remote page sizing and completion
|
||||
|
||||
Fast Fetch must obtain an authoritative target token from a normal changes-feed
|
||||
snapshot before consuming the stream. A request from `since=now` with no result
|
||||
rows provides a token in the same sequence domain as the streamed rows. If that
|
||||
target cannot be obtained, the fetch fails instead of falling back to a database
|
||||
information token, a document-count estimate, or another approximate sequence.
|
||||
Fast Fetch obtains an approximate progress target from a normal changes-feed
|
||||
request with `since=now`, `limit=1`, and `include_docs=false`. This token is for
|
||||
progress reporting only. It is not compared with any other token and is not
|
||||
used as a completion checkpoint.
|
||||
|
||||
The target token is treated as opaque. Fast Fetch completes only after the row
|
||||
for the captured target has been processed and all work up to that row has been
|
||||
persisted successfully. When a status request proves that no changes exist after
|
||||
the current durable checkpoint, the captured target may be checkpointed without
|
||||
opening the continuous stream. This includes an empty remote database. Changes
|
||||
made remotely after the target was captured are outside this Fast Fetch snapshot
|
||||
and are left for subsequent ordinary replication.
|
||||
Before every bounded page, Fast Fetch requests a normal changes feed from the
|
||||
current durable cursor with `limit=1` and `include_docs=false`. The probe and
|
||||
the following continuous page use the same `since`, style, and filter
|
||||
selection. Reading the probe does not consume rows from CouchDB; the continuous
|
||||
request starts again from that same cursor.
|
||||
|
||||
The estimated document count remains available for progress reporting only. It
|
||||
must not determine success.
|
||||
The number currently available is `results.length + pending`. If it is zero,
|
||||
Fast Fetch is caught up and completes without opening another stream. Otherwise,
|
||||
the next continuous request uses the smaller of that count and 10,000 as its
|
||||
finite `limit`.
|
||||
|
||||
Each finite page omits `heartbeat` and sets `timeout=1000`. This lets CouchDB
|
||||
3.2 return the page's terminator one second after it exhausts the currently
|
||||
available changes, rather than keeping the request open for future writes. The
|
||||
client immediately reconnects from that terminator while another normal probe
|
||||
reports available work. This bounded cycle also preserves the intent of the
|
||||
earlier iOS and iPadOS heartbeat workaround: Fast Fetch no longer depends on a
|
||||
silent continuous request eventually closing at CouchDB's default 60-second
|
||||
timeout.
|
||||
|
||||
The probe and page are separate HTTP requests, not a transactional snapshot.
|
||||
New writes, replica selection, or administrative changes may alter the rows
|
||||
between them. A page which returns at least one row and a valid terminator may
|
||||
therefore be shorter than the probe's estimate. Fast Fetch persists that page
|
||||
and probes again. A page which terminates without making progress after a
|
||||
positive probe is a retryable transport failure, avoiding an unbounded busy
|
||||
loop.
|
||||
|
||||
Each continuous request ends with its own `{ "last_seq": ... }` line. Fast
|
||||
Fetch treats that line separately from a changes row, flushes and validates all
|
||||
preceding local writes, and only then persists the opaque `last_seq`. The exact
|
||||
value is replayed as the next request's `since`; it is never parsed, ordered, or
|
||||
compared with a row's `seq`, another request's `last_seq`, or the database's
|
||||
`update_seq`.
|
||||
|
||||
The limit counts outer changes-result rows. A tombstone is one row and consumes
|
||||
one page slot even when no document body is present. With `style=all_docs`,
|
||||
multiple leaf revisions inside one row's `changes` array do not consume
|
||||
additional slots. Changing `include_docs` between the lightweight probe and the
|
||||
document-bearing continuous page changes the payload, not the row selection.
|
||||
|
||||
### Processing and persistence
|
||||
|
||||
@@ -68,8 +123,9 @@ stages:
|
||||
1. parse and validate the changes-feed row;
|
||||
2. decrypt and validate its document, when a document is present;
|
||||
3. add the document to the pending local batch;
|
||||
4. persist the batch; and
|
||||
5. inspect every result returned by the batch write.
|
||||
4. persist the batch;
|
||||
5. inspect every result returned by the batch write; and
|
||||
6. after the finite page ends, persist its `last_seq` terminator.
|
||||
|
||||
With `new_edits: false`, PouchDB follows CouchDB behaviour and may omit successful
|
||||
results. Fast Fetch therefore inspects every returned result and treats any
|
||||
@@ -79,8 +135,8 @@ the complete batch.
|
||||
The checkpoint may advance only to the last contiguous sequence for which all
|
||||
preceding documents are durable. A row which legitimately requires no local
|
||||
write may advance the checkpoint only after any preceding buffered documents
|
||||
have been flushed successfully. The target sequence is committed under the same
|
||||
rule before the operation reports success.
|
||||
have been flushed successfully. A page's `last_seq` is committed under the same
|
||||
rule before that page reports success.
|
||||
|
||||
If a batch is partly written, its checkpoint is not advanced. Retrying the batch
|
||||
with `new_edits: false` is expected to be idempotent, including for documents
|
||||
@@ -90,8 +146,8 @@ Blank heartbeat lines are ignored. Malformed rows are failures; they are not
|
||||
silently skipped. Logs may describe the stage and sequence involved, but must
|
||||
not include the raw changes-feed line because it may be large or sensitive.
|
||||
|
||||
The continuous changes request and its decoded reader must be terminated on
|
||||
every exit. Releasing a reader lock alone does not cancel the underlying
|
||||
Each finite continuous changes request and its decoded reader must be terminated
|
||||
on every exit. Releasing a reader lock alone does not cancel the underlying
|
||||
request. Failure and completion paths therefore abort the request and attempt
|
||||
to cancel the reader before the bounded remote-activity scope ends.
|
||||
|
||||
@@ -156,7 +212,7 @@ The responsibilities are divided at three injectable boundaries.
|
||||
|
||||
The Commonlib streaming implementation owns HTTP response validation, NDJSON
|
||||
parsing, invocation of the decryption delegate, batch-write result validation,
|
||||
contiguous checkpoint advancement, target-sequence completion, and classified
|
||||
contiguous checkpoint advancement, finite-page completion, and classified
|
||||
failures. It does not know about the Vault, setup dialogues, flag files, or
|
||||
LiveSync settings.
|
||||
|
||||
@@ -187,7 +243,8 @@ This decision does not:
|
||||
- add an automatic fallback from Fast Fetch to Standard Fetch;
|
||||
- define the detailed failure dialogue or other setup user-interface changes;
|
||||
or
|
||||
- require Fast Fetch to include remote changes made after its captured target.
|
||||
- provide a transaction or locked snapshot across the normal probe and the
|
||||
following continuous page.
|
||||
|
||||
An explicit Standard Fetch choice remains available when a user needs the
|
||||
ordinary replication path. Any automatic fallback or richer recovery dialogue
|
||||
@@ -209,8 +266,20 @@ writer. Verify that:
|
||||
- a partly failed batch leaves the checkpoint unchanged and reports a storage
|
||||
failure;
|
||||
- rows without a local write flush earlier buffered documents before advancing;
|
||||
- an estimated document count cannot complete the fetch;
|
||||
- the captured target cannot complete the fetch before its batch is durable;
|
||||
- a returned probe row is counted in addition to `pending`, including when
|
||||
`pending` is zero;
|
||||
- every probe uses `limit=1`, excludes document bodies, and is repeated from the
|
||||
previous page's opaque terminator;
|
||||
- each bounded page omits `heartbeat`, uses `timeout=1000`, and can complete
|
||||
under CouchDB 3.2 after its current rows have been delivered;
|
||||
- deletion and document-less rows consume a page slot;
|
||||
- a row count cannot complete a page without its `last_seq` terminator;
|
||||
- a page terminator cannot advance the checkpoint before its batch is durable;
|
||||
- a final row and `last_seq` with different opaque representations complete
|
||||
normally without a token comparison;
|
||||
- a shorter valid page is persisted and followed by another probe, while a
|
||||
zero-row page after a positive probe fails without looping;
|
||||
- workloads over 10,000 rows resume from each durable finite-page checkpoint;
|
||||
- authentication and malformed-protocol responses are terminal;
|
||||
- recognised transient transport failures are classified as retryable; and
|
||||
- diagnostics do not log the raw changes-feed line.
|
||||
@@ -236,9 +305,15 @@ existing setup sequence and cleanup.
|
||||
### Integration and E2E tests
|
||||
|
||||
Commonlib's CouchDB integration test remains responsible for the real HTTP
|
||||
changes feed, opaque sequence tokens, and local batch persistence. It should
|
||||
include a data set large enough to cross a batch boundary and confirm that the
|
||||
final checkpoint equals the captured target.
|
||||
changes feed, opaque sequence tokens, deletion rows, and local batch
|
||||
persistence. It should use the maintained CI CouchDB release, a two-shard
|
||||
database, and a data set large enough to cross a local batch boundary, and
|
||||
confirm that the final checkpoint can be passed back to CouchDB as `since` with
|
||||
no result rows or pending changes. The test must not compare that token's
|
||||
representation with a separately requested target or changes-row token. The
|
||||
focused regression test covers CouchDB 3.2's page-tail behaviour; compatibility
|
||||
with a real CouchDB 3.2 server can be confirmed manually without expanding the
|
||||
permanent CI matrix.
|
||||
|
||||
LiveSync's real Obsidian Setup URI workflow remains responsible for the actual
|
||||
Fast Fetch selection, E2EE passphrase, Vault reflection, ordinary file round
|
||||
@@ -256,8 +331,11 @@ This follows [Real Obsidian E2E](2026_06_real_obsidian_e2e.md).
|
||||
attempt without exposing the partial database to the Vault.
|
||||
- Retry delays are no longer spent on authentication, corrupt content, protocol,
|
||||
or local persistence failures which cannot repair themselves.
|
||||
- Progress totals remain approximate and may change without affecting
|
||||
correctness.
|
||||
- Progress totals remain approximate and may grow when a later probe observes
|
||||
new work, without affecting correctness.
|
||||
- A completed page can spend up to one second waiting for its terminator before
|
||||
Fast Fetch probes and reconnects. Active page transfer is not constrained to
|
||||
one second.
|
||||
- The implementation requires coordinated changes in Commonlib and LiveSync.
|
||||
Commonlib remains the authoritative package for streaming and rebuilder
|
||||
behaviour; LiveSync consumes an immutable Commonlib release and owns its setup
|
||||
@@ -265,3 +343,9 @@ This follows [Real Obsidian E2E](2026_06_real_obsidian_e2e.md).
|
||||
- Ordinary replication remains unchanged and continues to provide the reference
|
||||
correctness contract for decrypting, persisting, and checkpointing replicated
|
||||
documents.
|
||||
|
||||
## References
|
||||
|
||||
- [Apache CouchDB changes-feed API](https://docs.couchdb.org/en/stable/api/database/changes.html)
|
||||
- [Apache CouchDB 2.0 upgrade notes for opaque update sequences](https://docs.couchdb.org/en/stable/whatsnew/2.0.html#upgrade-notes)
|
||||
- [Apache CouchDB replication protocol](https://docs.couchdb.org/en/stable/replication/protocol.html)
|
||||
|
||||
@@ -1,145 +1,65 @@
|
||||
# How to report an issue
|
||||
|
||||
Thank you for helping improve Self-hosted LiveSync!
|
||||
Thank you for helping improve Self-hosted LiveSync. A concise report with the right evidence is more useful than trying several recovery operations before reporting the original symptom.
|
||||
|
||||
This document explains how to collect the information needed for an issue report. Issues with sufficient information will be prioritised.
|
||||
Use the [issue report template](https://github.com/vrtmrz/obsidian-livesync/issues/new?template=issue-report.md) for the report itself. Use [Troubleshooting](troubleshooting.md) to diagnose a symptom or choose a recovery action.
|
||||
|
||||
---
|
||||
## Preserve the original symptom
|
||||
|
||||
## Filled example
|
||||
Do not reset a database, rebuild a remote, change transport, or enable P2P merely to see whether the problem disappears. These actions can change the evidence and may make the original cause harder to identify.
|
||||
|
||||
Here is an example of a well-filled report for reference.
|
||||
If the problem may involve data loss, corruption, or unexpected deletion, preserve a copy of every readable affected file and stop editing it on other devices before changing settings.
|
||||
|
||||
### Abstract
|
||||
Include when the problem began, whether it followed an update or restart, how often it occurs, and which device and remote type were involved.
|
||||
|
||||
The synchronisation hung up immediately after connecting.
|
||||
## Required information
|
||||
|
||||
### Expected behaviour
|
||||
### Describe the behaviour
|
||||
|
||||
- Synchronisation ends with the message `Replication completed`
|
||||
- Everything synchronised
|
||||
Complete the issue template with:
|
||||
|
||||
### Actually happened
|
||||
- a one- or two-sentence summary;
|
||||
- the expected and actual behaviour;
|
||||
- repeatable steps, or the frequency and timing when reliable reproduction is not available; and
|
||||
- the role of each relevant device, such as the device where the change originated and the device where the failure appeared.
|
||||
|
||||
- Synchronisation was cancelled with the message `TypeError: Failed to fetch` (visible in the plug-in log around lines 10–12)
|
||||
- No files synchronised
|
||||
### Obsidian debug information
|
||||
|
||||
### Reproducing procedure
|
||||
Open the command palette with `Ctrl`+`P` or `Command`+`P`, run `Show debug info`, and include its output for each relevant device. The device where the problem appeared is required. Information from the other participating devices is particularly useful for synchronisation problems.
|
||||
|
||||
1. Configure LiveSync with the settings shown in the attached report.
|
||||
2. Click the sync button on the ribbon.
|
||||
3. Synchronisation begins.
|
||||
4. About two or three seconds later, the error `TypeError: Failed to fetch` appears.
|
||||
5. Replication stops. No files synchronised.
|
||||
### Full LiveSync report
|
||||
|
||||
### Obsidian debug info (Device 1 — Windows desktop)
|
||||
Run `Generate full report for opening the issue with debug info` on the device where the problem appeared. For a synchronisation problem, also collect a report from another participating device when its settings or logs are relevant. The command copies the current LiveSync settings summary and up to 1,000 recent log lines. It collects verbose log lines even when `Verbose Log` is disabled, so you do not need to enable that setting before reproducing the problem.
|
||||
|
||||
```
|
||||
SYSTEM INFO:
|
||||
Obsidian version: v1.2.8
|
||||
Installer version: v1.1.15
|
||||
Operating system: Windows 10 Pro 10.0.19044
|
||||
Login status: logged in
|
||||
Catalyst license: supporter
|
||||
Insider build toggle: off
|
||||
Community theme: Minimal v6.1.11
|
||||
Snippets enabled: 3
|
||||
Restricted mode: off
|
||||
Plugins installed: 35
|
||||
Plugins enabled: 11
|
||||
1: Self-hosted LiveSync v0.19.4
|
||||
...
|
||||
```
|
||||
The command automatically redacts known credential fields in the settings summary. It cannot guarantee that private text in log messages or unrecognised configuration fields is removed. Review the complete output before sharing it. Remove or replace:
|
||||
|
||||
### Report from LiveSync
|
||||
- usernames, passwords, passphrases, tokens, keys, and custom headers;
|
||||
- private server URLs, network addresses, database names, bucket names, room identifiers, and relay details;
|
||||
- Vault names, device names, and file paths; and
|
||||
- file contents or other private text which appears in a log message.
|
||||
|
||||
```
|
||||
----remote config----
|
||||
cors:
|
||||
credentials: "true"
|
||||
...
|
||||
---- Plug-in config ---
|
||||
couchDB_URI: self-hosted
|
||||
couchDB_USER: 𝑅𝐸𝐷𝐴𝐶𝑇𝐸𝐷
|
||||
...
|
||||
```
|
||||
Document and chunk identifiers can also be private metadata, but they may be necessary for diagnosing file reconstruction and chunk availability. Decide deliberately whether to share them. If you remove them, state that the report was redacted and that this may limit the diagnosis.
|
||||
|
||||
### Plug-in log
|
||||
For a large report, you may share a GitHub Gist after reviewing and redacting it. Deleting a Gist later cannot undo information which has already been disclosed.
|
||||
|
||||
```
|
||||
2023/5/24 10:50:33->HTTP:GET to:/ -> failed
|
||||
2023/5/24 10:50:33->TypeError:Failed to fetch
|
||||
2023/5/24 10:50:33->could not connect to https://example.com/ : your vault
|
||||
(TypeError:Failed to fetch)
|
||||
```
|
||||
## Additional evidence when relevant
|
||||
|
||||
---
|
||||
### A problem involving one file
|
||||
|
||||
## How to collect each piece of information
|
||||
Run `Copy database information for the active file`, or use **Hatch** → **Copy database information for a file** to select another file.
|
||||
|
||||
### Obsidian debug info
|
||||
This report describes only the local database on that device. It includes the Vault-relative path, document and chunk identifiers, local revisions, conflicts, and local chunk availability. It does not query the remote or include file contents. Review paths and identifiers as private metadata before sharing them.
|
||||
|
||||
Open the command palette (`Ctrl/Cmd + P`) and run **"Show debug info"**. Copy the output and paste it into the issue.
|
||||
### A problem which crosses a restart
|
||||
|
||||
If multiple devices are involved in the problem (e.g., sync between a phone and a desktop), please provide the debug info for each device. The device where the issue occurred is required; information from other devices is strongly recommended.
|
||||
Use `Write logs into the file` under **Hatch** only when the in-memory report cannot cover the restart. Persistent logging affects performance and can record private information. Disable it after reproducing the problem, review the log before sharing it, and remove the log file when it is no longer needed.
|
||||
|
||||
### Report from LiveSync (hatch report)
|
||||
### A connection, authentication, or CORS problem
|
||||
|
||||
1. Open LiveSync settings.
|
||||
2. Go to the **Hatch** pane.
|
||||
3. Press the **Make report** button.
|
||||
Include network evidence only when the ordinary LiveSync log cannot show the rejected response. Follow [Inspect a network failure](troubleshooting.md#inspect-a-network-failure), and remove request paths, remote addresses, authority and authorisation values, cookies, credentials, payload identifiers, and response secrets before sharing screenshots or copied data.
|
||||
|
||||
The report will be copied to your clipboard. It contains your LiveSync configuration and the remote server configuration, with credentials automatically redacted.
|
||||
## Sharing the report
|
||||
|
||||
**Tip:** For large reports, consider uploading to [GitHub Gist](https://gist.github.com/) and sharing the link instead of pasting directly into the issue. This makes it easier to manage, and if you accidentally leave sensitive data in, a Gist can be deleted.
|
||||
Paste reports into the matching collapsible sections in the issue template, or provide a link to an already-redacted Gist. A separate plug-in log is normally unnecessary because the full LiveSync report already contains the recent verbose log history.
|
||||
|
||||
If you paste directly, wrap it in a `<details>` tag to keep the issue readable:
|
||||
|
||||
```
|
||||
<details>
|
||||
<summary>Report from hatch</summary>
|
||||
|
||||
```
|
||||
----remote config----
|
||||
:
|
||||
```
|
||||
</details>
|
||||
```
|
||||
|
||||
### Plug-in log
|
||||
|
||||
The plug-in log is volatile by default (not saved to disk) and shown only in the log dialogue, which can be opened by tapping the **document box icon** in the ribbon.
|
||||
|
||||
#### Enable verbose log
|
||||
|
||||
Before reproducing the issue, enable **Verbose Log** in LiveSync's **General Settings** pane. Without this, many diagnostic messages will be suppressed.
|
||||
|
||||
#### Persist the log to a file (optional)
|
||||
|
||||
If you need to capture a log across a restart, enable **"Write logs into the file"** in General Settings. Note that log files may contain sensitive information — use this option only for troubleshooting, and disable it afterwards.
|
||||
|
||||
As with the hatch report, consider uploading large logs to [GitHub Gist](https://gist.github.com/).
|
||||
|
||||
### Network log (for connection-related issues only)
|
||||
|
||||
If the issue is related to network connectivity (e.g., cannot connect to the server, authentication errors), a network log captured from browser DevTools can be very helpful. You do not need to include this for non-connection issues.
|
||||
|
||||
#### Opening DevTools
|
||||
|
||||
| Platform | Shortcut |
|
||||
|----------|----------|
|
||||
| Windows / Linux | `Ctrl + Shift + I` |
|
||||
| macOS | `Cmd + Shift + I` |
|
||||
| Android | Use [Chrome remote debugging](https://developer.chrome.com/docs/devtools/remote-debugging/) |
|
||||
| iOS | Use [Safari Web Inspector](https://developer.apple.com/documentation/safari-developer-tools/inspecting-ios) on a Mac |
|
||||
|
||||
#### What to capture
|
||||
|
||||
1. Open the **Network** pane in DevTools.
|
||||
2. Reproduce the issue.
|
||||
3. Look for requests marked in red.
|
||||
4. Capture screenshots of the **Headers**, **Payload**, and **Response** tabs for those requests.
|
||||
|
||||
**Important — redact before sharing:**
|
||||
- Headers: conceal the request URL path, Remote Address, `authority`, and `authorisation` values.
|
||||
- Payload / Response: the `_id` field contains your file paths — redact if needed.
|
||||
If a maintainer asks for a more specialised diagnostic, collect only that additional evidence and review it again before publishing it.
|
||||
|
||||
@@ -117,6 +117,8 @@ Enable Obsidian's `Detect all file extensions`, then check LiveSync selectors, i
|
||||
|
||||
## Collect a report
|
||||
|
||||
Follow [How to report an issue](to_issue_reporting.md) for the complete reporting checklist, including Obsidian debug information and the privacy review required before sharing evidence.
|
||||
|
||||
Run `Generate full report for opening the issue with debug info` to copy the current settings summary and recent verbose log lines. Remove credentials, remote URLs, Vault names, file contents, and other private information before sharing it.
|
||||
|
||||
When a problem concerns one file, run **Copy database information for the active file**, or use **Hatch** → **Copy database information for a file** to select another file. The report describes this device's local database view, including the Vault-relative path, document and chunk identifiers, local database revisions, conflicts, and local chunk availability. It does not query the remote server or include file contents. Treat paths and identifiers as private metadata before sharing.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.10",
|
||||
"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",
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.10",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-livesync",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.10",
|
||||
"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.6",
|
||||
"@vrtmrz/livesync-commonlib": "0.1.9",
|
||||
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
||||
"@vrtmrz/ui-interactions": "0.1.2",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
@@ -4775,9 +4775,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vrtmrz/livesync-commonlib": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.6.tgz",
|
||||
"integrity": "sha512-rKpiTZYZRLaYcBQ2gcSyPGa9HONtataIB75dfP9+6BFlq/KzXimhKf1RqWxkAJj5GGzKmhtq+vXXExA+vAshMQ==",
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.9.tgz",
|
||||
"integrity": "sha512-qacNUbRAqt32j756XTTdI5K+/co8oc2BKjzsUAhEsDHC8tc18q4a3cQrUHNJuxYO+nYnx0FKhf9lHMZcCX+Scg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.808.0",
|
||||
@@ -15924,7 +15924,7 @@
|
||||
},
|
||||
"src/apps/cli": {
|
||||
"name": "self-hosted-livesync-cli",
|
||||
"version": "1.0.7-cli",
|
||||
"version": "1.0.10-cli",
|
||||
"dependencies": {
|
||||
"chokidar": "^4.0.0",
|
||||
"minimatch": "^10.2.5",
|
||||
@@ -15949,7 +15949,7 @@
|
||||
},
|
||||
"src/apps/webapp": {
|
||||
"name": "livesync-webapp",
|
||||
"version": "1.0.7-webapp",
|
||||
"version": "1.0.10-webapp",
|
||||
"dependencies": {
|
||||
"octagonal-wheels": "^0.1.52"
|
||||
},
|
||||
@@ -15961,7 +15961,7 @@
|
||||
}
|
||||
},
|
||||
"src/apps/webpeer": {
|
||||
"version": "1.0.7-webpeer",
|
||||
"version": "1.0.10-webpeer",
|
||||
"dependencies": {
|
||||
"octagonal-wheels": "^0.1.52"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.10",
|
||||
"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.6",
|
||||
"@vrtmrz/livesync-commonlib": "0.1.9",
|
||||
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
||||
"@vrtmrz/ui-interactions": "0.1.2",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "self-hosted-livesync-cli",
|
||||
"private": true,
|
||||
"version": "1.0.7-cli",
|
||||
"version": "1.0.10-cli",
|
||||
"main": "dist/index.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "livesync-webapp",
|
||||
"private": true,
|
||||
"version": "1.0.7-webapp",
|
||||
"version": "1.0.10-webapp",
|
||||
"type": "module",
|
||||
"description": "Browser-based Self-hosted LiveSync using FileSystem API",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "webpeer",
|
||||
"private": true,
|
||||
"version": "1.0.7-webpeer",
|
||||
"version": "1.0.10-webpeer",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -150,7 +150,7 @@ export function createFetchAllFlagHandler(
|
||||
// Select the remote database if there are multiple remotes configured.
|
||||
const isRemoteActivated = await askAndActivateRemoteDatabase(host, log);
|
||||
if (!isRemoteActivated) {
|
||||
return false;
|
||||
return await cancelScheduledInitialisation(host, cleanupFlag);
|
||||
}
|
||||
|
||||
// Ask user for use Fast Setup
|
||||
|
||||
@@ -581,6 +581,16 @@ describe("Red Flag Feature", () => {
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(host.mocks.ui.confirm.confirmWithMessage).not.toHaveBeenCalled();
|
||||
expect(host.mocks.storageAccess.files.has(FlagFilesOriginal.FETCH_ALL)).toBe(false);
|
||||
await expect(handler.check()).resolves.toBe(false);
|
||||
expect(host.mocks.setting.applyPartial).toHaveBeenCalledWith(
|
||||
{
|
||||
suspendFileWatching: true,
|
||||
suspendParseReplicationResult: true,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(host.mocks.appLifecycle.performRestart).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("should activate selected remote configuration", async () => {
|
||||
|
||||
@@ -30,12 +30,15 @@ Deno.test({
|
||||
const aggregator = await browser.newPage();
|
||||
const assertNoAggregatorFailures = observePageFailures(aggregator);
|
||||
const assertNoAggregatorNetworkFailures = observeNetworkFailures(aggregator);
|
||||
await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=0&d=first-", server.baseUrl).href);
|
||||
await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=0&d=before%2", server.baseUrl).href);
|
||||
await aggregator.getByText("1 / 2 Loaded", { exact: true }).waitFor();
|
||||
await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=1&d=second", server.baseUrl).href);
|
||||
await aggregator.goto(
|
||||
new URL("aggregator.html#id=pages-smoke&n=2&i=1&d=3after%26amp%2Bplus%25percent", server.baseUrl)
|
||||
.href
|
||||
);
|
||||
assertEquals(
|
||||
await aggregator.getByRole("link", { name: "Open Obsidian to complete setup" }).getAttribute("href"),
|
||||
"obsidian://setuplivesync?settingsQR=first-second"
|
||||
"obsidian://setuplivesync?settingsQR=before%23after%26amp%2Bplus%25percent"
|
||||
);
|
||||
assertNoAggregatorFailures();
|
||||
assertNoAggregatorNetworkFailures();
|
||||
|
||||
36
updates.md
36
updates.md
@@ -12,6 +12,42 @@ Earlier releases remain available in the 0.25 release history and the legacy rel
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.0.10
|
||||
|
||||
9th August, 2026
|
||||
|
||||
### Setup and compatibility
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fast Setup now sends configured CouchDB custom headers with every changes-feed request, allowing reverse proxies such as Cloudflare Access to authenticate initial setup in the same way as ordinary synchronisation ([Commonlib PR #82](https://github.com/vrtmrz/livesync-commonlib/pull/82)). Thank you to @nimula for the contribution!
|
||||
|
||||
## 1.0.9
|
||||
|
||||
8th August, 2026
|
||||
|
||||
For the first time in a while, I published a release that could not be promoted to a stable release. Sorry about that! I am glad that we caught it while it was still a pre-release.
|
||||
|
||||
### Setup and compatibility
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Multi-part settings QR codes now preserve special characters in passwords, passphrases, and other settings (PR #1083). Thank you to @calvinbui for the improvement!
|
||||
- Fast Setup now sizes each finite CouchDB changes page from a one-row status probe, counts the returned result together with `pending`, and resumes from the page's opaque `last_seq` without comparing token representations. Each page uses a one-second idle timeout instead of a heartbeat, allowing CouchDB 3.2 to return its terminator after the currently available rows have been persisted.
|
||||
|
||||
## 1.0.8
|
||||
|
||||
8th August, 2026
|
||||
|
||||
This version was published for pre-release validation only and was not promoted to a stable release.
|
||||
|
||||
### Setup and compatibility
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fast Setup now sizes each finite CouchDB changes page from a one-row status probe, counts the returned result together with `pending`, and resumes from the page's opaque `last_seq` without comparing token representations. Heartbeat-enabled feeds no longer wait for future writes after the currently available rows have been persisted (#1065).
|
||||
- Cancelling remote selection during a scheduled Fetch now removes the Fetch flag before restarting with file and database reflection paused, preventing the same selection dialogue from reopening on every start-up.
|
||||
|
||||
## 1.0.7
|
||||
|
||||
8th August, 2026
|
||||
|
||||
@@ -19,5 +19,8 @@
|
||||
"1.0.4": "1.7.2",
|
||||
"1.0.5": "1.7.2",
|
||||
"1.0.6": "1.7.2",
|
||||
"1.0.7": "1.7.2"
|
||||
"1.0.7": "1.7.2",
|
||||
"1.0.8": "1.7.2",
|
||||
"1.0.9": "1.7.2",
|
||||
"1.0.10": "1.7.2"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user