diff --git a/.dockerignore b/.dockerignore index ec80feb0..a3ee67b0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -15,8 +15,9 @@ main_org.js pouchdb-browser.js production/ -# Test coverage and reports +# Test coverage and reports coverage/ +_testdata/ test/bench-network/bench-results/ src/apps/cli/testdeno/bench-results/ diff --git a/docs/adr/2026_07_common_library_package_boundary.md b/docs/adr/2026_07_common_library_package_boundary.md index 68fd4f47..67a65cba 100644 --- a/docs/adr/2026_07_common_library_package_boundary.md +++ b/docs/adr/2026_07_common_library_package_boundary.md @@ -2,7 +2,7 @@ ## Status -Proposed — the implementation proof is complete, and `@vrtmrz/livesync-commonlib@0.1.0-rc.1` has been published and verified as the exact downstream dependency; the community-scanner preview remains pending. +Proposed — the implementation proof is complete, and `@vrtmrz/livesync-commonlib@0.1.0-rc.2` has been published and verified as the exact downstream dependency; the community-scanner preview remains pending. ## Context @@ -245,13 +245,15 @@ Every retained barrel must correspond to an explicit `exports` entry, list named ## Implementation Proof -The package proof builds Commonlib as one compiled ESM package with a small root, `context`, `browser`, `node`, and `rpc` entries, plus the explicit compatibility exports required by the current downstream migration. It publishes neither raw TypeScript nor Svelte source. The immutable `@vrtmrz/livesync-commonlib@0.1.0-rc.1` registry artefact can be installed into a clean consumer, imported in Node, type-checked from declarations, and bundled independently for browser context, browser storage, browser services, and workers. Its registry version and checksum are recorded by release validation. +The package proof builds Commonlib as one compiled ESM package with a small root, `context`, `browser`, `node`, and `rpc` entries, plus the explicit compatibility exports required by the current downstream migration. It publishes neither raw TypeScript nor Svelte source. The immutable `@vrtmrz/livesync-commonlib@0.1.0-rc.2` registry artefact can be installed into a clean consumer, imported in Node, type-checked from declarations, and bundled independently for browser context, browser storage, browser services, and workers. Its registry version and checksum are recorded by release validation. The proof found and fixed three boundary defects which source-alias consumption had hidden: compiled JSON imports required explicit output extensions, precompiled Svelte output could not safely be treated as source by the downstream Svelte pipeline, and Vite's default client conditions selected Commonlib's browser worker while building the Node CLI. Packed-consumer regressions cover the first two. The CLI now uses Vite's server conditions and treats every Node built-in reported by Commonlib's Node entry as external; the built CLI is exercised through Deno E2E. Importing root or context also no longer patches DOM prototypes, translator injection prevents the context entry from loading the complete language catalogue, and standard input and protocol output are supplied by the package-owned host contract rather than direct stream access in command handlers. -Self-hosted LiveSync, its CLI, Webapp, WebPeer, plug-in source, and tests compile against that exact registry artefact without `@lib/*`. Focused downstream storage tests pass against the package-owned Node and File System Access API implementations. The old `src/lib` Git submodule, generated `_types` fallback, type-generation scripts, and source aliases are removed by the proof branch. +Self-hosted LiveSync, its CLI, Webapp, WebPeer, plug-in source, and tests compile against that exact registry artefact without `@lib/*`. Focused downstream storage tests pass against the package-owned Node and File System Access API implementations. Commonlib also owns the Trystero implementation and version; the host retains no direct Trystero dependency, preventing two transport generations from entering one application graph. The old `src/lib` Git submodule, generated `_types` fallback, type-generation scripts, and source aliases are removed by the proof branch. -The Commonlib contract suite passes 21 tests covering Context results, both platform storage implementations, and standard I/O; its complete suite passes 1,092 tests across 57 files. Self-hosted LiveSync's three host-composition contract tests and complete 340-test unit suite pass against the registry artefact. The plug-in, CLI, Webapp, and WebPeer production builds also pass. The CLI contract command completes its nine-step Deno workflow against the built Node artefact. +The Commonlib contract suite passes 21 tests covering Context results, both platform storage implementations, and standard I/O; its complete suite passes 1,123 tests across 62 files. Self-hosted LiveSync's three host-composition contract tests and complete 341-test unit suite across 38 files pass against the registry artefact. The plug-in, CLI, Webapp, and WebPeer production builds also pass. The CLI contract command completes its nine-step Deno workflow against the built Node artefact. + +The package-owned Trystero transport also completes the canonical Compose P2P synchronisation workflow with a local relay and two isolated CLI peers. In real Obsidian, the plug-in starts with one consistent `ObsidianServiceContext`, the representative server-selection and Setup URI Svelte dialogues mount and close through their normal controls, their mobile variants satisfy viewport, safe-area, and touch-target assertions, and the settings pane exposes only the effective deletion controls. These runtime checks complement the package tests without making Webapp maintenance the primary release gate. The Community review lint completes with no errors. Advisory warnings remain in pre-existing UI sentence casing, deprecated Obsidian interfaces, unchecked dynamic setting data, and application-specific console output, especially in the Webapp. They are separate follow-up work and do not justify widening the package boundary or exposing additional compatibility paths. diff --git a/package-lock.json b/package-lock.json index 2bfba016..81749d81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,7 @@ "@smithy/querystring-builder": "^4.2.9", "@smithy/types": "^4.14.3", "@smithy/util-retry": "^4.4.5", - "@trystero-p2p/nostr": "^0.24.0", - "@vrtmrz/livesync-commonlib": "0.1.0-rc.1", + "@vrtmrz/livesync-commonlib": "0.1.0-rc.2", "diff-match-patch": "^1.0.5", "fflate": "^0.8.2", "idb": "^8.0.3", @@ -3951,22 +3950,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@trystero-p2p/core": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/@trystero-p2p/core/-/core-0.24.0.tgz", - "integrity": "sha512-W5ATiflgzZLE21fN2VA3YsK2yBJEzCvhmJ/9q2Vm3QT/gcdqDpcBxsO0DYCy/wE1PBEwoB+A75eBNtGIGAPdxw==", - "license": "MIT" - }, - "node_modules/@trystero-p2p/nostr": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/@trystero-p2p/nostr/-/nostr-0.24.0.tgz", - "integrity": "sha512-LmsJSicsFU/rhmOWYaP/OxFl3rwGieX+q0eh0pAWUQM7IXbMu6tLC5+aAimtHitikPv9r6sck6EUTWMin8dBAw==", - "license": "MIT", - "dependencies": { - "@noble/secp256k1": "^3.1.0", - "@trystero-p2p/core": "0.24.0" - } - }, "node_modules/@tsconfig/svelte": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.8.tgz", @@ -4978,9 +4961,9 @@ } }, "node_modules/@vrtmrz/livesync-commonlib": { - "version": "0.1.0-rc.1", - "resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.0-rc.1.tgz", - "integrity": "sha512-OTZ2l1GyWBe7NWMRrWInZVfiGKTsh9zvjhpWj43Tsox/2JFNaa5LfZBunGV5UcjvGpD5cXGDAw94cQ9TdJBAdg==", + "version": "0.1.0-rc.2", + "resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.0-rc.2.tgz", + "integrity": "sha512-+aPm7TCLXlksOX43xXgl+I7hi6z8eJBFYvkdCtxJfk2DuWRG5V3akp0Z2CHss4J1L8mq4MDCAXKAALKP67uS+Q==", "license": "MIT", "dependencies": { "@aws-sdk/client-s3": "^3.808.0", @@ -4989,7 +4972,7 @@ "@smithy/middleware-apply-body-checksum": "^4.3.9", "@smithy/types": "^4.14.3", "@smithy/util-retry": "^4.4.5", - "@trystero-p2p/nostr": "^0.24.0", + "@trystero-p2p/nostr": "0.25.3", "diff-match-patch": "^1.0.5", "events": "^3.3.0", "fflate": "^0.8.2", @@ -5024,6 +5007,22 @@ } } }, + "node_modules/@vrtmrz/livesync-commonlib/node_modules/@trystero-p2p/core": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@trystero-p2p/core/-/core-0.25.3.tgz", + "integrity": "sha512-lQKNq/ha+vF6kQZrpaXJGzlzxLF/Fhizoy5dwJUYQlkqRrbPup/Jov2EpPX/CPr2X+f79HxVzonkeni3MxmCuQ==", + "license": "MIT" + }, + "node_modules/@vrtmrz/livesync-commonlib/node_modules/@trystero-p2p/nostr": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@trystero-p2p/nostr/-/nostr-0.25.3.tgz", + "integrity": "sha512-nZV9Fl/GXuhIkJSQ+wIkdMoRLO1oSTUL/+vZorukaojeAdOpT/61e8b9Vzbt8L1ktMTaGPEJHw2BG/B5BCwBuw==", + "license": "MIT", + "dependencies": { + "@noble/secp256k1": "^3.1.0", + "@trystero-p2p/core": "0.25.3" + } + }, "node_modules/@vrtmrz/obsidian-test-session": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@vrtmrz/obsidian-test-session/-/obsidian-test-session-0.2.0.tgz", diff --git a/package.json b/package.json index f82136dc..d5240692 100644 --- a/package.json +++ b/package.json @@ -158,8 +158,7 @@ "@smithy/querystring-builder": "^4.2.9", "@smithy/types": "^4.14.3", "@smithy/util-retry": "^4.4.5", - "@trystero-p2p/nostr": "^0.24.0", - "@vrtmrz/livesync-commonlib": "0.1.0-rc.1", + "@vrtmrz/livesync-commonlib": "0.1.0-rc.2", "diff-match-patch": "^1.0.5", "fflate": "^0.8.2", "idb": "^8.0.3", diff --git a/updates.md b/updates.md index 1b509aad..30061dde 100644 --- a/updates.md +++ b/updates.md @@ -1,13 +1,25 @@ -# 0.25 -Since 19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025) +# 1.0 -The head note of 0.25 is now in [updates_old.md](https://github.com/vrtmrz/obsidian-livesync/blob/main/updates_old.md). Because 0.25 got a lot of updates, thankfully, compatibility is kept and we do not need breaking changes! In other words, when get enough stabled. The next version will be v1.0.0. Even though it my hope. +Well then, everyone: it has been roughly a year since I declared the 0.25 beta. During that time, we have concentrated mainly on fixing defects and completing the features that the project needed. + +Version 1.0 has been in mind for some time. We have now brought together the work intended to make it possible: stronger CI, more detailed tests, an E2E runner suited to synchronisation, and real-device testing tools. These now form a coherent [Kit](https://github.com/vrtmrz/fancy-kit) rather than a collection of isolated pieces. + +With those foundations in place, it seems that the time has finally come to reshape the structure of this repository. + +None of this would have been possible without your issue reports, pull requests, sponsorship, and the support provided through [OpenAI's Codex for Open Source](https://openai.com/form/codex-for-oss/). I would like to express my gratitude once again. + +As with every pull request contributed to the project, code produced with Codex and similar tools is reviewed and audited by me, vrtmrz. Anyone interested in how I manage that process can refer to [my dotfiles](https://github.com/vrtmrz/dotfiles). + +Of course, this reorganisation is also being driven by necessity. The time has come to engage seriously with the Community directory review and to address reusability properly. After the rather dreadful score for v0.25.83, I even received an email about it. + +This will call for your help once again. I would be very grateful for your co-operation as we build a sounder foundation for the project and its future development. ## Unreleased ### Improved - Removed the ineffective 'Use the trash bin' toggle from the settings interface. Remote deletions continue to follow Obsidian's deletion preference, while the legacy setting key remains accepted for compatibility. +- Improved P2P restart and settings-reapplication handling by serialising transport start and stop, keeping event handlers bound to the active replicator, and using one package-owned Trystero transport generation. ### Miscellaneous @@ -19,6 +31,7 @@ The head note of 0.25 is now in [updates_old.md](https://github.com/vrtmrz/obsid - Added packed-package and downstream checks for Commonlib entry points, including isolated Node and browser File System Access API storage implementations. - Added reusable Context result contracts for Obsidian, CLI, and Webapp compositions, including a real-Obsidian smoke assertion that every service retains the host-provided Context. - Added Commonlib stream-contract tests and downstream CLI unit and Deno E2E coverage for injected text, binary, prompt, and error channels. +- Added a dependency-ownership regression and verified the package-owned P2P transport through Compose CLI synchronisation, real-Obsidian startup and Context checks, representative desktop and mobile dialogues, and the settings pane. ## 0.25.83 diff --git a/utils/commonlib-package-boundary.unit.spec.ts b/utils/commonlib-package-boundary.unit.spec.ts new file mode 100644 index 00000000..dc254759 --- /dev/null +++ b/utils/commonlib-package-boundary.unit.spec.ts @@ -0,0 +1,20 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +type PackageJson = Partial< + Record<"dependencies" | "devDependencies" | "optionalDependencies" | "peerDependencies", Record> +>; + +const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as PackageJson; + +describe("Commonlib package ownership", () => { + it("does not retain a host-owned Trystero dependency", () => { + const directDependencies = { + ...packageJson.dependencies, + ...packageJson.devDependencies, + ...packageJson.optionalDependencies, + ...packageJson.peerDependencies, + }; + expect(directDependencies).not.toHaveProperty("@trystero-p2p/nostr"); + }); +});