@vrtmrz/livesync-commonlib 0.1.34 → 0.1.36

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.
@@ -12,3 +12,4 @@ export { assessTweakCompatibility } from "./common/models/tweak.compatibility.js
12
12
  export type { TweakAssessment, TweakAssessmentEntry, TweakAssessmentRelation, TweakAssessmentValue, TweakTransition, TweakTransitionReason, } from "./common/models/tweak.compatibility.js";
13
13
  export type { TweakReconstruction, TweakValues } from "./common/models/tweak.definition.js";
14
14
  export type { ObsidianLiveSyncSettings, RemoteDBSettings, RemoteTypeSettings } from "./common/models/setting.type.js";
15
+ export { SETTINGS_PROPERTY_POLICY, SettingPolicies, createMarkdownSettings, mergeMarkdownSettings, type SettingPropertyPolicy, type MarkdownSettings, type CredentialFreeMarkdownSettings, type PersistedSettings, } from "./common/models/setting.policy.js";
package/dist/settings.js CHANGED
@@ -25,6 +25,12 @@ import {
25
25
  SettingsMigrationReviewCodes
26
26
  } from "./common/models/setting.lifecycle.js";
27
27
  import { assessTweakCompatibility } from "./common/models/tweak.compatibility.js";
28
+ import {
29
+ SETTINGS_PROPERTY_POLICY,
30
+ SettingPolicies,
31
+ createMarkdownSettings,
32
+ mergeMarkdownSettings
33
+ } from "./common/models/setting.policy.js";
28
34
  export {
29
35
  CURRENT_SETTING_VERSION,
30
36
  DEFAULT_SETTINGS,
@@ -36,13 +42,17 @@ export {
36
42
  PREFERRED_JOURNAL_SYNC,
37
43
  PREFERRED_SETTING_CLOUDANT,
38
44
  PREFERRED_SETTING_SELF_HOSTED,
45
+ SETTINGS_PROPERTY_POLICY,
39
46
  SETTINGS_SCHEMA_DEFAULTS,
47
+ SettingPolicies,
40
48
  SettingsMigrationReviewCodes,
41
49
  assessTweakCompatibility,
42
50
  configuredIdKey,
51
+ createMarkdownSettings,
43
52
  createNewVaultSettings,
44
53
  deriveIdKey,
45
54
  deriveOrImportIdKey,
46
55
  formatIdRecoveryCode,
56
+ mergeMarkdownSettings,
47
57
  prepareSettingsForLoad
48
58
  };
@@ -8,6 +8,10 @@ The code paths below identify the maintained Self-hosted LiveSync composition po
8
8
 
9
9
  ## Obsidian plug-in
10
10
 
11
+ The CouchDB connection fix bypasses browser HTTP caching so encrypted replication can continue after a remote Rebuild preserves document IDs and revisions. Commonlib's regression tests cover Metadata and Chunks encrypted with a replacement Security Seed while an earlier response remains cached. Self-hosted LiveSync's `couchdb-http-cache` scenario additionally populates the real browser HTTP cache before rebuilding, confirms that the Seed and ciphertext change while the revision remains unchanged, and requires subsequent replication to succeed without clearing that cache. The released LiveSync 1.0.34 fails this scenario; a local checked Commonlib artefact passes in the maintained LiveSync 1.0.34 composition on Linux Obsidian 1.12.7. This establishes the tested build's behaviour, with the reporter's Windows and Obsidian 1.13.7 environment still unverified.
12
+
13
+ Unreleased settings tests verify that Object Storage-only credentials, JWT values, and authentication headers reach the host persistence handler only after connection encryption, and that unavailable or failed required encryption preserves the previous persisted settings. The focused `/settings` entry also supplies conditional whole-profile Markdown preparation and import preservation. A clean packed consumer checks the exhaustive property policy and prepared output types with an ES2018 compile fixture. Commonlib owns these result and type contracts; Self-hosted LiveSync owns Markdown file writes, its settings interface, and restoration through a real Obsidian restart.
14
+
11
15
  Unreleased colon-path regression tests establish that Commonlib preserves ordinary file paths through Metadata storage, Chunk retrieval, and storage reflection, with path obfuscation enabled or disabled. They use real PouchDB with injected storage. This result does not establish which filenames a host's file-creation API accepts; that boundary requires host runtime verification.
12
16
 
13
17
  Commonlib's encryption tests verify that an obfuscated Metadata document retains its document ID while its HKDF-encrypted path and file properties round-trip, that V1-obfuscated paths remain readable through the fallback, and that PouchDB replication presents a decoded path to both local storage and change events. The Fast Fetch test verifies decryption before storage and checkpointing. On 26th September 2026, a local packed candidate of this fix passed LiveSync 1.0.31's `npm run check` and unit tests, as well as real Obsidian two-Vault synchronisation, encrypted CLI-to-Obsidian transfer, and encrypted Metadata retrieval through Fast Fetch during manual CouchDB onboarding.
@@ -34,6 +38,8 @@ The focused [Setup URI sharing API](setup-uri.md) adds a fixed time window for n
34
38
 
35
39
  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.
36
40
 
41
+ JSON patch tests verify that special property names remain own data properties during generation, application, object merging, and unordered array updates, while shared prototypes retain their original descriptors. A real in-memory PouchDB conflict test exercises the same helpers through `ConflictManager.mergeObject` and retains both non-conflicting JSON changes. These tests establish Commonlib's local JSON merge behaviour.
42
+
37
43
  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.
38
44
 
39
45
  Commonlib's chunk-reachability tests use real PouchDB revision trees. They verify that an ordinary superseded revision releases its unique chunks, a chunk shared by current files remains reachable, live conflict branches and their nearest available shared ancestor remain protected, and losing-branch ancestry becomes eligible after resolution. They also replicate a collected chunk deletion to another PouchDB database and verify that writing the same content can recreate and replicate the content-addressed chunk. Self-hosted LiveSync owns the CouchDB-specific Garbage Collection V3 workflow, including device checks, confirmation, deletion, push-only replication, and remote compaction.
@@ -72,6 +72,18 @@ Two other values deliberately remain unset until their owning lifecycle supplies
72
72
 
73
73
  The standard Commonlib `SettingService` performs this preparation automatically. Hosts which use that service can inspect `getSettingsMigrationState()` after `loadSettings()` instead of calling the function themselves.
74
74
 
75
+ ## Preparing settings for persistence and Markdown
76
+
77
+ `SettingService` prepares a separate settings object before calling the host's persistence handler. Object Storage credentials, CouchDB credentials, JWT values, and authentication headers share the existing `encryptedCouchDBConnection` payload. Encryption runs when any protected connection property is present, including when every CouchDB property is empty. The same policy supplies the properties encrypted, cleared before saving, and restored on loading. Older plaintext settings and encrypted payloads without newer properties remain readable.
78
+
79
+ An unavailable configuration passphrase or an empty connection-encryption result stops the save before the host's persistence handler receives the object. Remote profile URI encryption also stops on failure when a configuration passphrase is explicitly selected. The previous persisted settings remain intact. Removing all connection values clears an older encrypted payload only after it can be decrypted, preserving recovery after a failed decryption. Profile names, IDs, and selections remain ordinary settings; profile URIs are encrypted separately.
80
+
81
+ The focused `/settings` entry exports `SETTINGS_PROPERTY_POLICY` and the named `SettingPolicies` constants. Every schema property requires an explicit policy, including ordinary properties classified as `SettingPolicies.Default`. Adding a required or optional property without updating the table fails type checking. The named constants define the supported combinations of Markdown and persistence behaviour.
82
+
83
+ Hosts can use `createMarkdownSettings(settings)` to prepare an export. Its default follows `writeCredentialsForSettingSync`; an explicit boolean overrides that choice. When credentials are disabled, it omits credentials, the whole `remoteConfigurations` object, and both active-profile selections. When credentials are enabled, it retains the complete profile object and selections. Encrypted local payloads and runtime-only properties are always omitted. `mergeMarkdownSettings(incoming, current)` preserves omitted local values when importing a credential-free document.
84
+
85
+ `PersistedSettings` and `MarkdownSettings` carry preparation tags, so ordinary runtime settings cannot be passed directly to a handler which requires those types. `CredentialFreeMarkdownSettings` additionally excludes credential properties. These types check preparation boundaries; runtime policy checks and encryption tests establish the actual saved contents.
86
+
75
87
  ## Assessing synchronisation tweaks
76
88
 
77
89
  Use `assessTweakCompatibility(current, preferred)` from the focused `/settings` entry when comparing the synchronisation settings advertised by two sides. The result contains immutable, whitelisted snapshots, one entry for each compared setting, and directional `adoptPreferred` and `adoptCurrent` change sets. Each entry keeps the raw value and key-presence state separately from the effective value.
@@ -101,6 +113,6 @@ The settings schema version is independent of the package version and of any rem
101
113
 
102
114
  ## Tests owned by Commonlib
103
115
 
104
- The settings lifecycle unit tests cover blank stores, representative legacy choices, migration idempotence, legacy file-name case normalisation, legacy review state, future-schema downgrade protection, and the distinction between new-Vault recommendations and stored-setting fallbacks. Tweak-assessment tests cover effective defaults, unadvertised values, directional change sets, reconstruction impact, raw representation differences, immutable snapshots, and document-ID case behaviour. The packed-package test imports the focused `/settings` entry from a clean consumer and checks its declarations and runtime exports.
116
+ The settings lifecycle unit tests cover blank stores, representative legacy choices, migration idempotence, legacy file-name case normalisation, legacy review state, future-schema downgrade protection, and the distinction between new-Vault recommendations and stored-setting fallbacks. Credential tests cover Object Storage-only persistence, JWT and header restoration, legacy settings, removed credentials, encryption failures, conditional whole-profile Markdown export, and preservation of local values on import. Tweak-assessment tests cover effective defaults, unadvertised values, directional change sets, reconstruction impact, raw representation differences, immutable snapshots, and document-ID case behaviour. The packed-package test imports the focused `/settings` entry from a clean consumer and checks its declarations and runtime exports. Its ES2018 compile fixture checks missing policies and attempts to bypass prepared output types.
105
117
 
106
118
  Hosts remain responsible for testing when setup is classified as new, how local review acknowledgement is stored, how replication is gated, and how their settings interface presents the result.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrtmrz/livesync-commonlib",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
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",