@vrtmrz/livesync-commonlib 0.1.31 → 0.1.33

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 (57) hide show
  1. package/README.md +12 -0
  2. package/dist/API/DirectFileManipulatorV2.d.ts +2 -0
  3. package/dist/API/DirectFileManipulatorV2.js +17 -5
  4. package/dist/API/processSetting.d.ts +19 -0
  5. package/dist/API/processSetting.js +91 -6
  6. package/dist/common/idDerivation.d.ts +15 -0
  7. package/dist/common/idDerivation.js +102 -0
  8. package/dist/common/models/db.definition.d.ts +1 -0
  9. package/dist/common/models/setting.const.defaults.js +3 -0
  10. package/dist/common/models/setting.const.qr.js +4 -1
  11. package/dist/common/models/setting.type.d.ts +6 -0
  12. package/dist/common/models/tweak.compatibility.js +6 -2
  13. package/dist/common/models/tweak.definition.d.ts +8 -0
  14. package/dist/common/models/tweak.definition.js +4 -3
  15. package/dist/common/settingConstants.d.ts +3 -0
  16. package/dist/common/utils.js +3 -1
  17. package/dist/events/coreEvents.d.ts +3 -0
  18. package/dist/events/coreEvents.js +2 -0
  19. package/dist/hashing.d.ts +3 -0
  20. package/dist/hashing.js +4 -0
  21. package/dist/managers/EntryManager/EntryManagerImpls.js +10 -1
  22. package/dist/managers/HashManager/HashManager.d.ts +4 -0
  23. package/dist/managers/HashManager/HashManager.js +34 -2
  24. package/dist/managers/LiveSyncManagers.js +6 -0
  25. package/dist/pouchdb/LiveSyncDBFunctions.d.ts +1 -1
  26. package/dist/pouchdb/LiveSyncDBFunctions.js +33 -38
  27. package/dist/pouchdb/negotiation.js +7 -3
  28. package/dist/pouchdb/remoteFeatureCompatibility.d.ts +10 -0
  29. package/dist/pouchdb/remoteFeatureCompatibility.js +12 -1
  30. package/dist/pouchdb/remoteIdCompatibility.d.ts +5 -0
  31. package/dist/pouchdb/remoteIdCompatibility.js +28 -0
  32. package/dist/replication/CentralCompatibility.d.ts +1 -0
  33. package/dist/replication/CentralCompatibility.js +2 -1
  34. package/dist/replication/couchdb/LiveSyncReplicator.d.ts +6 -2
  35. package/dist/replication/couchdb/LiveSyncReplicator.js +24 -5
  36. package/dist/replication/journal/LiveSyncJournalReplicator.d.ts +1 -0
  37. package/dist/replication/journal/LiveSyncJournalReplicator.js +50 -5
  38. package/dist/replication/trystero/ProxiedDB.d.ts +1 -1
  39. package/dist/replication/trystero/TrysteroReplicator.d.ts +369 -5
  40. package/dist/replication/trystero/TrysteroReplicator.js +31 -4
  41. package/dist/services/base/AppLifecycleService.d.ts +2 -0
  42. package/dist/services/base/AppLifecycleService.js +5 -0
  43. package/dist/services/base/IService.d.ts +1 -0
  44. package/dist/services/base/PathService.d.ts +3 -1
  45. package/dist/services/base/PathService.js +9 -4
  46. package/dist/services/base/SettingService.js +47 -0
  47. package/dist/settings.d.ts +2 -1
  48. package/dist/settings.js +14 -0
  49. package/dist/setupUri.d.ts +6 -0
  50. package/dist/setupUri.js +14 -0
  51. package/dist/string_and_binary/path.d.ts +1 -1
  52. package/dist/string_and_binary/path.js +3 -3
  53. package/dist/worker/bgWorker.js +1 -1
  54. package/docs/proven-in-use.md +12 -0
  55. package/docs/releasing.md +1 -1
  56. package/docs/setup-uri.md +58 -0
  57. package/package.json +17 -1
@@ -16,12 +16,22 @@ The unreleased 0.1.30 packed candidate adds encryption of Hidden File Sync and C
16
16
 
17
17
  Additional real-CouchDB integration tests exercise Fast Fetch admission before local reset, generation 12 acceptance, and generation 13 retrieval with plaintext and encrypted internal Metadata together. A real-Obsidian migration scenario enables the preference through the settings UI without Rebuild, verifies that unchanged Metadata retains its original revision while rewritten entries are encrypted with stable IDs, and checks a second device's mismatch rejection and restoration after alignment. After turning the preference OFF, Fast Fetch still retrieves both representations and their Chunks with matching content; the remote feature declaration remains. These checks use the local packed candidate with LiveSync 1.0.32.
18
18
 
19
+ Optional independent ID derivation uses a saved secret for encrypted Chunk IDs and obfuscated document IDs. The unreleased Chunk update replaces the algorithm from `0.1.32`, published with the `next` tag, while retaining `idDerivationVersion: 1`, recovery codes, and settings. It hashes exact Chunk text with xxHash64 before HMAC-SHA-256 with a separate Chunk key. Preparation is shared per manager and current key; tests cover concurrent use, key changes, E2EE suspension, teardown, and retry after failure. Document IDs and agreement proofs retain their existing HMAC messages. Chunk collision resistance is bounded by the 64-bit prehash.
20
+
21
+ The updated Commonlib passes its complete Unit suite, type check, and isolated packed-package consumer checks. Real CouchDB and Object Storage Integration tests cover matching keys, direct-access rejection before control-document changes, Journal agreement, and differing Chunk keys when paths remain visible. LiveSync 1.0.32's Unit suite and build checks pass with the local packed candidate. Real Obsidian two-Vault checks cover matching-key synchronisation, incompatible document key rejection, and differing Chunk keys with visible paths. Its Review Harness exercises the actual calculation and copied report. Measurements use desktop Obsidian; native mobile timing and a complete Rebuild remain unmeasured for this construction.
22
+
23
+ The focused `/hashing` entry exposes the same `HashManager` used by database writes. Package checks exercise its types, a fixed ID vector through the installed Node module, and browser bundling. The Review Harness consumes that entry without importing the package's internal files. Earlier real-Obsidian onboarding, encrypted Journal upload, and CLI P2P Setup URI checks used the predecessor full-content-HMAC construction; they establish those integration paths but do not measure the updated algorithm. The local candidate is prepared as `0.1.33` for the `next` tag; registry publication remains separate from this evidence.
24
+
25
+ Regression tests also preserve each device's ID version and key through ordinary Tweak alignment, reject incompatible document ID modes separately from adoptable tweaks, and complete legacy P2P configuration imports without inheriting the receiving device's key. Direct-access admission checks cover both a different saved key and a legacy caller against keyed document IDs.
26
+
19
27
  The plug-in extends the neutral `ServiceContext` with Obsidian-owned capabilities in `src/modules/services/ObsidianServiceContext.ts`. One context instance carries the LiveSync-owned translator and event hub through the Service Hub rather than placing those dependencies in Commonlib globals. Commonlib supplies its typed English fallback when another host omits the translator.
20
28
 
21
29
  The consumer contract in `test/contracts/serviceContext.ts` checks shared result semantics and exact context identity across the composed services. The real-Obsidian suite documented in `test/e2e-obsidian/README.md` then covers plug-in loading, representative Svelte dialogue mounts, Vault reflection, CouchDB and Object Storage synchronisation, a two-device P2P Setup URI round-trip, two-Vault behaviour, and other Obsidian-owned boundaries.
22
30
 
23
31
  Commonlib supplies the two sleep preferences and preserves them through Setup URI encoding. Self-hosted LiveSync applies those values once at its injected bounded-activity runner, so remote operations and downloaded-document application share the same host-owned Wake Lock policy. Focused downstream tests cover the platform preference table and both activity categories; operating-system suspend behaviour remains real-platform integration evidence rather than a Commonlib guarantee.
24
32
 
33
+ The focused [Setup URI sharing API](setup-uri.md) adds a fixed time window for new Ephemeral exports while leaving Persistent exports in the existing format. Commonlib unit tests cover window boundaries, encrypted round trips, and old-reader compatibility for Persistent URIs. The Obsidian generation dialogue, CLI import, browser generators, and real-runtime behaviour remain downstream responsibilities; package-level coverage alone does not establish those host interactions.
34
+
25
35
  Commonlib's real-PouchDB and injected-boundary unit tests prove that conservative merge uses the nearest revision actually shared by both conflict leaves, multiple remaining leaves are selected in a deterministic order, each completed pair is reconstructed from the committed tree, storage content with exact provenance remains recognisable below a deleted losing branch after resolution, and ordinary file saves preserve edits below their recorded base or on an independent root when the base cannot be read. Incoming reflection uses the same classification. Current non-deleted leaf matches prevent duplicate preservation without using historical byte equality as proof of an unchanged file. Conflict-time deletion and rename retain their separate displayed-branch contracts. They also verify that a boolean history check stops after its first exact content match without reading an older unavailable revision, while revision enumeration still returns every match. Unknown-origin local content remains readable on a fresh independent root when the winning body is unavailable, including when the existing winner is generation one. A separately confirmed exact deletion of an unreadable current leaf remains an explicit repair operation. Exact reconciliation tests cover reflecting a selected live leaf, storing Vault content as its child, recording a matching leaf without creating a revision, clearing matching provenance after exact branch deletion, and refusing to record a stale revision or a revision whose content differs. Separate live-base tests advance a selected conflict leaf or logical-deletion leaf through PouchDB's ordinary revision check, retain the other live leaf, and reject reuse of a stale base. Self-hosted LiveSync supplies the host composition, persistent device-local provenance, and the per-revision repair interface. Its optional two-Vault scopes cover post-resolution propagation and edit, logical deletion, case-only rename, and cross-path rename while conflicts remain active. The conflict-operation scope passes in real Obsidian against the exact locally packed Commonlib artefact, including replicated parent revisions and preservation of the other live branches. Its Document History scenario restores readable historical bytes as a new live successor and reflects that exact revision to the Vault.
26
36
 
27
37
  The equal-time scan test uses real in-memory PouchDB to verify that a missing record is established from unchanged current content before a newer revision arrives. It also verifies that existing provenance is retained and equal-time local edits remain protected as conflicts. Focused handler tests cover failures and changes during verification. Self-hosted LiveSync owns the persistent store and real-Obsidian restart check; these Commonlib tests do not exercise Windows file events or remote CouchDB timing.
@@ -42,6 +52,8 @@ The strict aggregate remains the default for Fast Setup, Fetch, Rebuild, direct
42
52
 
43
53
  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, verbose diagnostics for rejected preparation stages, and the prevention of rebuilt events and later remote mutation after a failed local reset. Replication readiness tests verify that a descriptive application-initialisation diagnostic replaces the former bare diagnostic. Self-hosted LiveSync owns settings persistence, setup flags, user-facing notices, recovery dialogue, and real-Obsidian rebuild confirmation; those host results remain downstream evidence rather than Commonlib guarantees.
44
54
 
55
+ Commonlib's lifecycle tests verify that `markIsReady()` emits `EVENT_APPLICATION_READY` on the service context's event channel once per transition to readiness, after the flag is set, and that clearing readiness emits nothing. On 27th September 2026, a local packed candidate passed LiveSync 1.0.32's type check and replication unit tests together with a result processor which continues held replication results from that event, and a temporary downstream test showed documents restored during a real `prepareDatabaseForUse()` run held until readiness and applied immediately afterwards. Behaviour in a real Obsidian Vault remains downstream runtime evidence.
56
+
45
57
  The focused `/replication` entry defines the provider capability, configuration identity, same-kind reconciliation, interaction authority, and truthful outcome contracts used when a host composes replication. A host selects its fixed provider subset and registers each definition during composition; an omitted role remains an explicit unsupported result rather than falling back to another provider. Commonlib serialises active replacement, rejects a candidate whose configuration changes before publication, and provides a transition-aware context acquisition boundary. The entry does not own user dialogue, P2P room policy, or selection of unknown providers.
46
58
 
47
59
  The same entry distinguishes a central provider whose host prepares the Security Seed from one which prepares it within each transfer. Object Storage uses the latter: Journal reads fresh synchronisation parameters before compatibility checks, shares that result with its checkpoint epoch and encryption work, and releases it when the transfer settles. CouchDB retains host preparation. Focused Commonlib tests cover read reuse, later refresh, unavailable storage, and checkpoint reset; the maintained plug-in's provider tests and packed-package checks cover the declared readiness. Behaviour on the reporter's Android device remains a downstream runtime check.
package/docs/releasing.md CHANGED
@@ -33,7 +33,7 @@ Before publication, run the downstream workflow against an exact Self-hosted Liv
33
33
 
34
34
  ## Preparing a release
35
35
 
36
- Choose the version explicitly. Use a prerelease such as `0.1.0-rc.0` when registry installation must be validated before the first stable version. Package-proof versions are local artefacts and cannot be staged.
36
+ Choose the version explicitly. Prefer a `-next.N` prerelease, such as `0.1.32-next.0`, when registry installation must be validated before the stable version. Reserve `-rc.N` for an explicitly chosen release candidate. Package-proof versions are local artefacts and cannot be staged.
37
37
 
38
38
  Prepare both stable releases and pre-releases on a reviewed pull request based on `main`. A pre-release may be staged from the exact reviewed pull-request branch commit so that the registry artefact can be validated in Self-hosted LiveSync before the Commonlib change is merged. A stable release must be staged only after its exact reviewed release commit is present on `main`.
39
39
 
@@ -0,0 +1,58 @@
1
+ # Setup URI sharing
2
+
3
+ The focused `@vrtmrz/livesync-commonlib/setup-uri` entry encodes and decodes
4
+ encrypted Setup URIs. A Setup URI carries settings and remote credentials;
5
+ share its URI and passphrase separately.
6
+
7
+ `encodeTimeBoundSetupURI` offers two generation modes. `ephemeral` is the
8
+ default. It binds the URI to the current seven-day UTC window, anchored at the
9
+ Unix epoch, and returns the exclusive end of that window as `usableUntil` in
10
+ Unix milliseconds. This is a fixed window, so a newly generated URI may have
11
+ less than seven days remaining. Show the returned instant in the user's time
12
+ zone when presenting the URI.
13
+
14
+ `persistent` returns `usableUntil: null` and delegates to the original
15
+ `encodeSettingsToSetupURI` algorithm with the entered passphrase. A reader
16
+ which already supports that original encryption format can open it. Both modes
17
+ have the same URI structure and carry no visible mode or timestamp field.
18
+
19
+ ```ts
20
+ import {
21
+ encodeTimeBoundSetupURI,
22
+ decodeSettingsFromSetupURI,
23
+ getTimeBoundSetupURIUsableUntil,
24
+ isTimeBoundSetupURIUsableNow,
25
+ } from '@vrtmrz/livesync-commonlib/setup-uri';
26
+
27
+ const endShownBeforeGeneration = getTimeBoundSetupURIUsableUntil();
28
+ const generated = await encodeTimeBoundSetupURI(settings, enteredPassphrase, {
29
+ mode: 'ephemeral',
30
+ removeProperties: ['pluginSyncExtendedSetting'],
31
+ skipDefaultValue: true,
32
+ });
33
+
34
+ const importedSettings = await decodeSettingsFromSetupURI(generated.uri.trim(), enteredPassphrase);
35
+ const canStillCopy = isTimeBoundSetupURIUsableNow(generated.usableUntil);
36
+ const endWasAccurate = generated.usableUntil === endShownBeforeGeneration;
37
+ ```
38
+
39
+ The decoder automatically tries the current Ephemeral window and the entered
40
+ passphrase. Previous and future windows are not searched. Existing Setup URIs
41
+ remain readable. An Ephemeral URI cannot be opened through the unchanged old
42
+ decoder with the entered passphrase.
43
+
44
+ The receiving device supplies the clock. Someone who knows the passphrase
45
+ can reproduce historical time factors or alter that clock. Opening a URI does
46
+ not revoke credentials already imported, and Ephemeral does not mean one-time
47
+ use. An unsuccessful opening attempt cannot reliably distinguish an incorrect
48
+ passphrase, damaged ciphertext, or a different time window.
49
+
50
+ The encoder checks that its Ephemeral window has not changed during encryption.
51
+ `getTimeBoundSetupURIUsableUntil` lets a host show the exact end before a user
52
+ selects the mode. Compare that value with the generated `usableUntil` and
53
+ present the new end if the window changed during selection. A host may also use
54
+ `isTimeBoundSetupURIUsableNow` before showing or copying an open result; it
55
+ checks both edges of the selected window, including a clock moved backwards to
56
+ an earlier window. An already open copy dialogue can otherwise retain a URI
57
+ after its window ends, but the reader will reject that URI. The selected export
58
+ mode is an interaction choice; it is not a synchronised Vault setting.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrtmrz/livesync-commonlib",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
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",
@@ -47,6 +47,11 @@
47
47
  "import": "./dist/context.js",
48
48
  "default": "./dist/context.js"
49
49
  },
50
+ "./hashing": {
51
+ "types": "./dist/hashing.d.ts",
52
+ "import": "./dist/hashing.js",
53
+ "default": "./dist/hashing.js"
54
+ },
50
55
  "./node": {
51
56
  "types": "./dist/platform/node/index.d.ts",
52
57
  "import": "./dist/platform/node/index.js",
@@ -77,6 +82,11 @@
77
82
  "import": "./dist/settings.js",
78
83
  "default": "./dist/settings.js"
79
84
  },
85
+ "./setup-uri": {
86
+ "types": "./dist/setupUri.d.ts",
87
+ "import": "./dist/setupUri.js",
88
+ "default": "./dist/setupUri.js"
89
+ },
80
90
  "./compat/API/processSetting": {
81
91
  "types": "./dist/API/processSetting.d.ts",
82
92
  "import": "./dist/API/processSetting.js",
@@ -633,6 +643,9 @@
633
643
  "context": [
634
644
  "dist/context.d.ts"
635
645
  ],
646
+ "hashing": [
647
+ "dist/hashing.d.ts"
648
+ ],
636
649
  "node": [
637
650
  "dist/platform/node/index.d.ts"
638
651
  ],
@@ -651,6 +664,9 @@
651
664
  "settings": [
652
665
  "dist/settings.d.ts"
653
666
  ],
667
+ "setup-uri": [
668
+ "dist/setupUri.d.ts"
669
+ ],
654
670
  "compat/API/processSetting": [
655
671
  "dist/API/processSetting.d.ts"
656
672
  ],