@vrtmrz/livesync-commonlib 0.1.17 → 0.1.19-rc.0

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 (46) hide show
  1. package/dist/API/DirectFileManipulatorV2.js +3 -1
  2. package/dist/common/ConnectionString.js +9 -1
  3. package/dist/common/models/fileaccess.type.d.ts +7 -0
  4. package/dist/common/models/setting.const.d.ts +18 -0
  5. package/dist/common/models/setting.const.defaults.js +10 -1
  6. package/dist/common/models/setting.const.js +12 -0
  7. package/dist/common/models/setting.const.qr.js +3 -1
  8. package/dist/common/models/setting.p2p.d.ts +21 -0
  9. package/dist/common/models/setting.p2p.js +35 -0
  10. package/dist/common/models/setting.type.d.ts +11 -1
  11. package/dist/common/models/shared.definition.configNames.js +8 -0
  12. package/dist/common/models/tweak.definition.d.ts +2 -0
  13. package/dist/common/settingConstants.d.ts +2 -0
  14. package/dist/common/types.d.ts +5 -3
  15. package/dist/common/types.js +17 -1
  16. package/dist/common/utils.js +4 -1
  17. package/dist/interfaces/DatabaseRebuilder.d.ts +4 -2
  18. package/dist/managers/StorageEventManager.d.ts +16 -5
  19. package/dist/managers/StorageEventManager.js +46 -8
  20. package/dist/pouchdb/LiveSyncLocalDB.d.ts +7 -1
  21. package/dist/pouchdb/LiveSyncLocalDB.js +120 -38
  22. package/dist/replication/trystero/LiveSyncTrysteroReplicator.d.ts +8 -0
  23. package/dist/replication/trystero/LiveSyncTrysteroReplicator.js +36 -8
  24. package/dist/replication/trystero/TrysteroReplicatorP2PServer.js +2 -2
  25. package/dist/rpc/transports/TrysteroTransport.d.ts +2 -0
  26. package/dist/rpc/transports/TrysteroTransport.js +18 -2
  27. package/dist/rpc/transports/trysteroUtils.js +12 -1
  28. package/dist/serviceFeatures/prepareDatabaseForUse.js +18 -15
  29. package/dist/serviceModules/Rebuilder.d.ts +27 -4
  30. package/dist/serviceModules/Rebuilder.js +113 -35
  31. package/dist/serviceModules/ServiceFileHandlerBase.d.ts +17 -0
  32. package/dist/serviceModules/ServiceFileHandlerBase.js +145 -9
  33. package/dist/services/base/DatabaseService.d.ts +11 -3
  34. package/dist/services/base/DatabaseService.js +63 -7
  35. package/dist/services/base/IService.d.ts +1 -0
  36. package/dist/services/base/ReplicationService.d.ts +16 -0
  37. package/dist/services/base/ReplicationService.js +36 -4
  38. package/dist/services/base/ReplicatorService.d.ts +1 -0
  39. package/dist/services/base/ReplicatorService.js +32 -13
  40. package/dist/worker/bgWorker.js +1 -1
  41. package/docs/development.md +2 -0
  42. package/docs/p2p-transport-lifecycle.md +4 -2
  43. package/docs/proven-in-use.md +5 -1
  44. package/docs/releasing.md +24 -0
  45. package/docs/remote-configurations.md +2 -0
  46. package/package.json +1 -1
@@ -69,6 +69,8 @@ The one-shot CouchDB connectivity preflight is the first bounded consumer. It ap
69
69
 
70
70
  `openSimpleStore()` may create an inert namespace handle during composition, before the backing key-value database has opened. Maintained hosts must complete their sequential settings lifecycle before scans, watchers, or replication invoke the handle. Operations fail on a lifecycle violation rather than waiting for readiness; do not introduce an implicit wait which can hang after failed initialisation or become self-referential from an initialisation handler. Treat database reset as a transient unavailable boundary and reconstruct derived local state after reopening.
71
71
 
72
+ The active local database identity, settings-selected reset sequence, and lifecycle event phases are specified in [Local database lifecycle](database-lifecycle.md). Extend that document and the focused service and rebuild tests whenever database selection, reset ownership, event ordering, or failure propagation changes.
73
+
72
74
  ### P2P composition ownership
73
75
 
74
76
  `useP2PReplicatorFeature` is the sole owner of the active `LiveSyncTrysteroReplicator` and its lifecycle bindings. It creates or replaces the outer replicator when `ReplicatorService` requests one, closes the previous instance before replacement, shares an in-flight replacement between concurrent callers, and returns a stable result object whose `replicator` property resolves the current instance.
@@ -31,7 +31,9 @@ It is therefore a logical LiveSync disconnection and a physical signalling-serve
31
31
 
32
32
  ## Reconnection and replacement
33
33
 
34
- An explicit open resumes Trystero relay reconnection before joining the configured room. Settings application may change the relay URLs, room ID, passphrase, or TURN configuration, so the owning service closes and discards the former LiveSync instance before constructing the replacement. Concurrent replacement requests share the same in-flight replacement and receive the same new owner. No fixed close-to-open delay is required: lifecycle operations are serialised, and peer readiness is observed through discovery.
34
+ An explicit open resumes Trystero relay reconnection before joining the configured room. Settings application may change the relay URLs, room ID, passphrase, or TURN configuration, so the owning service normally closes and discards the former LiveSync instance before constructing the replacement. Concurrent replacement requests share the same in-flight replacement and receive the same new owner.
35
+
36
+ A retained `LiveSyncTrysteroReplicator` also compares the effective outgoing message bound and connection path on every open. An unchanged signature keeps the serving transport, while a changed signature serialises closure of that transport before opening its replacement. This prevents a selected compatibility profile from appearing to take effect while the former room binding is still active. No fixed close-to-open delay is required: lifecycle operations are serialised, and peer readiness is observed through discovery.
35
37
 
36
38
  Saving settings with P2P or automatic start disabled always requests `close()`, even when the room has not started serving. This cancels an in-flight open through the same lifecycle queue, so a connection cannot appear after the disabling setting has been applied.
37
39
 
@@ -53,7 +55,7 @@ Commonlib consequently does not expose a forced physical-disconnection command.
53
55
 
54
56
  Maintain all five boundaries when this lifecycle changes:
55
57
 
56
- - Commonlib unit tests must prove that normal close leaves the room without directly closing Trystero-owned peers, that disabling settings cancel a pending open, and that concurrent replacement requests leave one current owner;
58
+ - Commonlib unit tests must prove that normal close leaves the room without directly closing Trystero-owned peers, that disabling settings cancel a pending open, that concurrent replacement requests leave one current owner, and that a changed compatibility signature replaces a serving transport while an unchanged signature remains idempotent;
57
59
  - Commonlib rebuild tests must prove that first-device P2P initialisation does not reset a remote database and that an additional-device P2P Fetch performs one explicit peer-selection pass before resuming reflection;
58
60
  - the Self-hosted LiveSync Compose P2P lifecycle test must replace a current replicator, rediscover the same real peer, perform bidirectional RPC, and verify transferred content from a separate process;
59
61
  - 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
@@ -24,7 +24,9 @@ Commonlib's injected remote-service tests verify that an owning operation can ab
24
24
 
25
25
  Commonlib's remote-preference result contract distinguishes available synchronisation settings, a remote which has not stored those settings yet, a failed read, and a remote type which does not support central preferences. Focused CouchDB and Object Storage tests cover absent milestone data separately from transport failures, while Self-hosted LiveSync owns the initialisation choices, cancellation policy, and user-facing explanation.
26
26
 
27
- Commonlib's full offline scanner distinguishes completed, deliberately skipped, and failed storage/database pairs. Before pair construction, it withholds Metadata whose actual document ID disagrees with its recorded path, without reflection, deletion, or last-seen side effects. A consistently addressed entry for the same logical path continues through the established path-based flow; only a path without such an entry also withholds storage processing. The read-only actual-ID Inspector and separately invoked one-entry repair retain ambiguous states for review, revalidate an exact source revision, verify a target-first copy, and preserve the source on failure. Self-hosted LiveSync keeps the existing Fast Setup aggregate policy and owns confirmation and presentation in its file/database repair interface.
27
+ Commonlib's full offline scanner distinguishes completed, deliberately skipped, and failed storage/database pairs. Before pair construction, it withholds Metadata whose actual document ID disagrees with its recorded path, without reflection, deletion, or last-seen side effects. A consistently addressed entry for the same logical path continues through the established path-based flow; only a path without such an entry also withholds storage processing. The read-only actual-ID Inspector and separately invoked one-entry repair retain ambiguous states for review, revalidate an exact source revision, verify a target-first copy, and preserve the source on failure. Snapshot-restoration tests additionally verify that restored inclusions use current storage content, stale deletions are suppressed, rename halves are admitted from their current path states, and an inspection failure does not become evidence of absence. The following full scan remains the final reconciliation step. Self-hosted LiveSync keeps the existing Fast Setup aggregate policy and owns confirmation and presentation in its file/database repair interface.
28
+
29
+ Commonlib's local-database lifecycle tests distinguish the settings-selected database from the active wrapper. They verify replacement before a changed-suffix reset, fail-closed cleanup after rejected physical preparation, application readiness after the requested scan and completion hooks, and the prevention of rebuilt events and later remote mutation after a failed local reset. Self-hosted LiveSync owns settings persistence, setup flags, recovery dialogue, and real-Obsidian rebuild confirmation; those host results remain downstream evidence rather than Commonlib guarantees.
28
30
 
29
31
  Most replication and storage services used by the plug-in still enter through explicit `compat/*` paths. Those imports prove that the published compatibility boundary supports the current migration; they are not examples of a finished high-level client API.
30
32
 
@@ -56,6 +58,8 @@ The browser service composition in `src/apps/browser/createLiveSyncBrowserServic
56
58
 
57
59
  The Obsidian plug-in, CLI, WebApp, and WebPeer compose P2P ownership through `useP2PReplicatorFeature`. Commands and views retain its live result object and resolve the current replicator when an action occurs. Downstream Deno and Compose P2P E2E cover headless peer discovery and synchronisation, including the WebApp-to-WebPeer-to-CLI journey. Application-owned Chromium checks cover the browser UI flows, and the public Pages deployment has separate post-deployment smoke validation. The real-Obsidian Setup URI workflow additionally covers first-device local initialisation, one-pass additional-device Fetch, explicit peer approval, Vault reflection, and a two-way note round-trip.
58
60
 
61
+ Commonlib's focused P2P compatibility tests establish legacy defaulting, bounded outgoing message sizes, connection-string and QR-setting round trips, application of the configured bound across its Trystero server and client surfaces, relay-only ICE mapping when a valid TURN URL is present, and replacement of a serving transport when an effective compatibility value changes. They do not prove that a particular network path requires a smaller preset or that a configured TURN service can allocate a relay. Self-hosted LiveSync owns profile selection, user-facing controls, and real-Obsidian composition; device- and network-specific connectivity remains downstream or reporter-environment evidence.
62
+
59
63
  This is evidence that the current package boundary can be consumed without the Obsidian host, but it is not yet a recommended standalone Commonlib client factory. The high-level lifecycle, readiness, error, and disposal contract remains future package work after Self-hosted LiveSync 1.0 rather than a gate for that release.
60
64
 
61
65
  ## LiveSync Bridge
package/docs/releasing.md CHANGED
@@ -13,6 +13,8 @@ npm run verify:package
13
13
 
14
14
  The gate type-checks Commonlib, runs its complete unit suite, verifies the source boundary, builds the distributable package, installs its exact tarball into a clean consumer, and bundles representative browser and Node entry points. The source `package.json` remains private to prevent publishing the repository root. Only the generated `.package` directory is publishable, and its manifest defaults to public publication on the `next` dist-tag.
15
15
 
16
+ The package builder normalises generated directories to `0755`, ordinary files to `0644`, and declared `bin` targets to `0755` before validation. `test:package` uses a restrictive umask and verifies the packed modes, so local and hosted builds do not differ only because their caller environments use different umasks.
17
+
16
18
  ### Lockfile reproducibility
17
19
 
18
20
  Regenerate `package-lock.json` with the reviewed npm CLI version pinned by the `Use the reviewed npm CLI` step in `.github/workflows/publish-npm.yml`. Do this after adding, removing, or updating a dependency, even when an older local npm reports that the lockfile is already up to date. npm minor versions can differ in how they record transitive optional peer dependencies; a lockfile accepted by an older client can otherwise fail the hosted `npm ci` before any tests run.
@@ -90,3 +92,25 @@ gh workflow run publish-npm.yml \
90
92
  For a stable release, use `source_ref=main`. The workflow rejects a stable release selected from another branch, rejects a stable release without its trusted workflow commit, and requires the workflow-triggering SHA to equal the packaged `main` SHA. The workflow dispatch itself uses `--ref main` for every release, so an unmerged branch cannot change the trusted publication job or acquire access to the `npm` environment.
91
93
 
92
94
  The workflow always stages to `next`. Inspect the staged package name, version, access, dist-tag, provenance, checksum, files, selected source branch, and source commit before approving it through npm. Approval and later promotion to `latest` are separate user-authorised operations. Keep the Commonlib and Self-hosted LiveSync consumer pull requests in draft while validating the exact registry pre-release. If validation fails, leave that published version immutable and prepare a new pre-release. After successful consumer validation, merge Commonlib only through its separate maintainer gate. Validate a stable release in Self-hosted LiveSync before promoting it to `latest`.
95
+
96
+ ## Publishing a GitHub Release
97
+
98
+ Create a GitHub Release for each stable Commonlib release after the exact registry artefact has passed downstream validation and the version has been promoted to `latest`. Target the exact `main` commit used to build the published package.
99
+
100
+ Protect the GitHub `github-release` environment with a required reviewer and permit only `main`. The manually dispatched workflow first verifies the release with read-only repository access. Only its protected publication job receives `contents: write` access.
101
+
102
+ Set the exact version and release commit, then dispatch the workflow from `main`:
103
+
104
+ ```bash
105
+ version='<version>'
106
+ release_sha='<full-release-commit>'
107
+ gh workflow run publish-github-release.yml \
108
+ --ref main \
109
+ -f version="$version" \
110
+ -f expected_sha="$release_sha" \
111
+ -f confirmation="release @vrtmrz/livesync-commonlib@$version from $release_sha"
112
+ ```
113
+
114
+ The workflow requires the release commit to be an ancestor of its trusted `main` commit, reads the exact source version and corresponding release notes from that commit, confirms that npm `latest` points to the version, and rejects an existing version tag. Review those results before approving the `github-release` environment. The protected job rechecks npm `latest`, then creates the version tag and GitHub Release and verifies that the tag points to the selected commit.
115
+
116
+ Treat dispatching and approving the GitHub Release workflow as separate user-authorised remote operations. Verify the version, exact release commit, and release notes immediately before approval.
@@ -42,6 +42,8 @@ There is no special profile named or identified as `default`. The selected main
42
42
  - Use `{ activate: true, activateForP2P: true }` when P2P is the main remote.
43
43
  - Use `{ activateForP2P: true }` to select a P2P profile without changing the main remote.
44
44
 
45
+ The outgoing message bound and connection path are ordinary P2P profile properties retained in its connection URI. Separate profiles may intentionally share a Group ID and credentials while selecting different transport compatibility values; only the profile selected by `P2P_ActiveRemoteConfigurationId` supplies the active flat P2P projection.
46
+
45
47
  Selecting a profile updates the compatibility fields immediately. Existing replication services may therefore continue to consume those fields while profile-aware hosts treat the profile map and selection IDs as authoritative persisted state.
46
48
 
47
49
  ## Import and migration boundary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrtmrz/livesync-commonlib",
3
- "version": "0.1.17",
3
+ "version": "0.1.19-rc.0",
4
4
  "description": "Shared data, storage, and replication primitives for Self-hosted LiveSync clients.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",