From 3ea8eac21215ceaedb893a43b6af7b1c998ccc45 Mon Sep 17 00:00:00 2001 From: vorotamoroz Date: Tue, 25 Aug 2026 10:29:21 +0000 Subject: [PATCH] Reduce deprecated API and dependency warnings --- ...2026_07_common_library_package_boundary.md | 2 +- docs/adr/2026_07_feature_maturity_for_1_0.md | 2 +- package-lock.json | 435 +++++++----------- src/apps/cli/package.json | 2 +- src/common/compatibilitySettings.ts | 32 ++ src/common/compatibilitySettings.unit.spec.ts | 22 + src/modules/core/ModuleReplicator.ts | 13 +- src/modules/essential/ModuleMigration.ts | 5 +- .../essential/ModuleMigration.unit.spec.ts | 30 +- src/modules/extras/ModuleDev.ts | 21 - src/modules/extras/devUtil/TestPane.svelte | 118 ----- src/modules/extras/devUtil/TestPaneView.ts | 53 --- src/modules/extras/devUtil/tests.ts | 89 ---- .../features/SettingDialogue/PanePatches.ts | 8 +- 14 files changed, 256 insertions(+), 576 deletions(-) create mode 100644 src/common/compatibilitySettings.ts create mode 100644 src/common/compatibilitySettings.unit.spec.ts delete mode 100644 src/modules/extras/devUtil/TestPane.svelte delete mode 100644 src/modules/extras/devUtil/TestPaneView.ts delete mode 100644 src/modules/extras/devUtil/tests.ts diff --git a/docs/adr/2026_07_common_library_package_boundary.md b/docs/adr/2026_07_common_library_package_boundary.md index 43be51da..495af16c 100644 --- a/docs/adr/2026_07_common_library_package_boundary.md +++ b/docs/adr/2026_07_common_library_package_boundary.md @@ -275,7 +275,7 @@ The dependency preview also reports `uuid`, but the installed and locked graph r The 1.0 dependency review found newly disclosed parser and denial-of-service advisories with compatible fixes. All locked `brace-expansion` generations now use their patched releases, including the production generation reached by Commonlib path matching and the CLI's user-configured ignore patterns. The development-only ESLint and Istanbul `js-yaml` generations likewise use patched releases. The production Markdown parser uses the patched `linkify-it` release to avoid quadratic processing of maliciously structured `mailto:` links, while the development-only JSON Schema toolchain uses the patched `fast-uri` release for unambiguous hostname parsing. A clean install and both complete and production-only `npm audit` checks no longer report these packages. -The remaining audit report is the existing `werift` and `werift-ice` dependency on `ip`, for which npm offers no patched version. The advisory concerns `ip.isPublic()` misclassifying unusual loopback representations. The locked werift implementation uses `ip` for address encoding, decoding, format detection, and loopback filtering, but does not call `isPublic()` or `isPrivate()`. LiveSync reaches werift only through the Node CLI's injected `RTCPeerConnection`; the Obsidian plug-in and browser applications use their platform WebRTC implementation, and the plug-in artefact does not contain werift. The package-level finding is therefore accepted for the 1.0 integration preview as a non-reachable advisory in the reviewed call path, not as a general waiver. Revisit it when werift or `ip` publishes a replacement, or before any change which delegates address trust, routing, or URL access decisions to that dependency. +The initial 1.0 dependency review also found `werift` and `werift-ice` pulling in `ip`, for which npm offers no patched version. The advisory concerns `ip.isPublic()` misclassifying unusual loopback representations. LiveSync reached werift only through the Node CLI's injected `RTCPeerConnection`, and the reviewed call path did not use `isPublic()` or `isPrivate()`. This temporary acceptance ended when werift removed the dependency: the CLI now uses `werift` 0.24.4 or later, the installed production graph contains no `ip` package, and `npm audit --omit=dev` reports no vulnerabilities. The local real-Obsidian suite verifies the actual loaded `ObsidianServiceContext`, all 18 services, Vault reflection, CouchDB and Object Storage transfer, remote-activity accounting, CLI-to-Obsidian encrypted synchronisation, startup scanning, two-Vault create, update, delete, ordinary rename, case-only rename, target mismatch, Hidden File Sync, Customisation Sync, setting Markdown export, and two-device CouchDB, Object Storage, and P2P Setup URI workflows. These checks establish observable results and host composition rather than relying on declaration compatibility alone. diff --git a/docs/adr/2026_07_feature_maturity_for_1_0.md b/docs/adr/2026_07_feature_maturity_for_1_0.md index c1668947..a4117d7c 100644 --- a/docs/adr/2026_07_feature_maturity_for_1_0.md +++ b/docs/adr/2026_07_feature_maturity_for_1_0.md @@ -34,7 +34,7 @@ Version 1.0 needs to distinguish supported opt-in features from previews and fro - `xxhash64` is the current hash contract. Other hash algorithms remain available for existing databases and edge-case recovery, not as experimental alternatives for new Vaults. - Eden chunks remain accepted at runtime and in transported settings, but are not offered in the settings interface. - `doNotUseFixedRevisionForChunks` remains an inert compatibility input. Chunk revisions are always content-derived. -- The deprecated cleaned-database reconciliation callback remains internal while an old IndexedDB client may still encounter that remote state. It is not a user-selectable maintenance action and is omitted from the settings reference. +- The cleaned-database compatibility path remains internal while an old IndexedDB client may still encounter that remote state. It is not a user-selectable maintenance action and is omitted from the settings reference. ### Already removed diff --git a/package-lock.json b/package-lock.json index e0517b7e..092948ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1192,15 +1192,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", @@ -2321,12 +2312,6 @@ "ret": "~0.1.10" } }, - "node_modules/@minhducsun2002/leb128": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@minhducsun2002/leb128/-/leb128-1.0.0.tgz", - "integrity": "sha512-eFrYUPDVHeuwWHluTG1kwNQUEUcFjVKYwPkU8z9DR1JH3AW7JtJsG9cRVGmwz809kKtGfwGJj58juCZxEvnI/g==", - "license": "MIT" - }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", @@ -2443,128 +2428,167 @@ } }, "node_modules/@peculiar/asn1-cms": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz", - "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.9.4.tgz", + "integrity": "sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "@peculiar/asn1-x509-attr": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "@peculiar/asn1-x509-attr": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-csr": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz", - "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.9.4.tgz", + "integrity": "sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-ecc": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz", - "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.9.4.tgz", + "integrity": "sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-pfx": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz", - "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.9.4.tgz", + "integrity": "sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==", "license": "MIT", "dependencies": { - "@peculiar/asn1-cms": "^2.6.1", - "@peculiar/asn1-pkcs8": "^2.6.1", - "@peculiar/asn1-rsa": "^2.6.1", - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", + "@peculiar/asn1-cms": "^2.9.4", + "@peculiar/asn1-pkcs8": "^2.9.4", + "@peculiar/asn1-rsa": "^2.9.4", + "@peculiar/asn1-schema": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-pkcs8": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz", - "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.9.4.tgz", + "integrity": "sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-pkcs9": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz", - "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.9.4.tgz", + "integrity": "sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==", "license": "MIT", "dependencies": { - "@peculiar/asn1-cms": "^2.6.1", - "@peculiar/asn1-pfx": "^2.6.1", - "@peculiar/asn1-pkcs8": "^2.6.1", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "@peculiar/asn1-x509-attr": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-cms": "^2.9.4", + "@peculiar/asn1-pfx": "^2.9.4", + "@peculiar/asn1-pkcs8": "^2.9.4", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "@peculiar/asn1-x509-attr": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-rsa": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz", - "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.9.4.tgz", + "integrity": "sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-schema": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", - "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.4.tgz", + "integrity": "sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==", "license": "MIT", "dependencies": { - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-x509": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz", - "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.9.4.tgz", + "integrity": "sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, "node_modules/@peculiar/asn1-x509-attr": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz", - "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.9.4.tgz", + "integrity": "sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, @@ -3001,11 +3025,6 @@ "node": ">=0.10.0" } }, - "node_modules/@shinyoshiaki/jspack": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@shinyoshiaki/jspack/-/jspack-0.0.6.tgz", - "integrity": "sha512-SdsNhLjQh4onBlyPrn4ia1Pdx5bXT88G/LIEpOYAjx2u4xeY/m/HB5yHqlkJB1uQR3Zw4R3hBWLj46STRAN0rg==" - }, "node_modules/@smithy/abort-controller": { "version": "4.2.12", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.12.tgz", @@ -3922,6 +3941,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/dom-mediacapture-transform": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-transform/-/dom-mediacapture-transform-0.1.12.tgz", + "integrity": "sha512-d7/QsLRwF864A5mgIM/YrfiglHoYn7zgCcAoJgW404r+2DwnNr7EBbLnCWpmOMgH8y0te73L1AV6H1bmauaWFw==", + "license": "MIT", + "dependencies": { + "@types/dom-webcodecs": "*" + } + }, + "node_modules/@types/dom-webcodecs": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz", + "integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==", + "license": "MIT" + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -4394,7 +4428,7 @@ "version": "8.56.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5151,12 +5185,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "license": "MIT" - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -5601,13 +5629,13 @@ } }, "node_modules/asn1js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", - "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", "license": "BSD-3-Clause", "dependencies": { "pvtsutils": "^1.3.6", - "pvutils": "^1.1.3", + "pvutils": "^1.1.5", "tslib": "^2.8.1" }, "engines": { @@ -6067,6 +6095,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -6634,26 +6663,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8434,6 +8448,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, "license": "MIT" }, "node_modules/fast-fifo": { @@ -9397,12 +9412,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/int64-buffer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-1.1.0.tgz", - "integrity": "sha512-94smTCQOvigN4d/2R/YDjz8YVG0Sufvv2aAh8P5m42gwhCsDAJqnbNOrxJsrADuAFAA69Q/ptGzxvNcNuIJcvw==", - "license": "MIT" - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -9418,12 +9427,6 @@ "node": ">= 0.4" } }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "license": "MIT" - }, "node_modules/ip-address": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", @@ -10919,6 +10922,7 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, "license": "MIT" }, "node_modules/lodash-es": { @@ -11087,6 +11091,24 @@ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "license": "MIT" }, + "node_modules/mediabunny": { + "version": "1.55.2", + "resolved": "https://registry.npmjs.org/mediabunny/-/mediabunny-1.55.2.tgz", + "integrity": "sha512-EEx4O6qYddAdCyWPMZNDwI7uc5hewNHrPAf9jLcVhIbXoPsiqNQ+D9i1pfadmGkjN2V318jSrZljkpoziYm6Lg==", + "license": "MPL-2.0", + "workspaces": [ + ".", + "packages/*" + ], + "dependencies": { + "@types/dom-mediacapture-transform": "^0.1.11", + "@types/dom-webcodecs": "0.1.13" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/Vanilagy" + } + }, "node_modules/memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", @@ -11204,12 +11226,6 @@ "node": "*" } }, - "node_modules/mp4box": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mp4box/-/mp4box-0.5.4.tgz", - "integrity": "sha512-GcCH0fySxBurJtvr0dfhz0IxHZjc1RP+F+I8xw+LIwkU1a+7HJx8NCDiww1I5u4Hz6g4eR1JlGADEGJ9r4lSfA==", - "license": "BSD-3-Clause" - }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -11577,15 +11593,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -12571,9 +12578,9 @@ } }, "node_modules/pvutils": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", - "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", + "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", "license": "MIT", "engines": { "node": ">=16.0.0" @@ -12947,11 +12954,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rx.mini": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rx.mini/-/rx.mini-1.4.0.tgz", - "integrity": "sha512-8w5cSc1mwNja7fl465DXOkVvIOkpvh2GW4jo31nAIvX4WTXCsRnKJGUfiDBzWtYRInEcHAUYIZfzusjIrea8gA==" - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -13876,21 +13878,6 @@ } } }, - "node_modules/svelte-check/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/svelte-eslint-parser": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-1.8.0.tgz", @@ -15249,137 +15236,25 @@ "link": true }, "node_modules/werift": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/werift/-/werift-0.23.0.tgz", - "integrity": "sha512-/WcIN5DHFG9Ri4anGOmIkp8gxBGFMWSIB/m4sfZ5CWlLfD3iMhiaAUuTBuc+KV3SY9NDmvmLtiN2uaM7k3lVzw==", + "version": "0.24.4", + "resolved": "https://registry.npmjs.org/werift/-/werift-0.24.4.tgz", + "integrity": "sha512-NoROZ11L/ZqAB5ombCB4VBuVNdIZfwI493zlxlIX7BlwfWRy55eDJdtWMC2VX35yBXFaWwA8NtYbmJ8qWtVk9Q==", "license": "MIT", "dependencies": { "@fidm/x509": "^1.2.1", - "@minhducsun2002/leb128": "^1.0.0", "@noble/curves": "^1.8.1", "@peculiar/x509": "^1.12.3", "@shinyoshiaki/binary-data": "^0.6.1", - "@shinyoshiaki/jspack": "^0.0.6", - "aes-js": "^3.1.2", "buffer": "^6.0.3", "debug": "4.4.0", - "fast-deep-equal": "^3.1.3", - "int64-buffer": "1.1.0", - "ip": "^2.0.1", - "mp4box": "^0.5.3", + "mediabunny": "^1.45.2", "multicast-dns": "^7.2.5", - "tweetnacl": "^1.0.3", - "werift-common": "*", - "werift-dtls": "*", - "werift-ice": "*", - "werift-rtp": "*", - "werift-sctp": "*" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/werift-common": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/werift-common/-/werift-common-0.0.3.tgz", - "integrity": "sha512-ma3E4BqKTyZVLhrdfTVs2T1tg9seeUtKMRn5e64LwgrogWa62+3LAUoLBUSl1yPWhgSkXId7GmcHuWDen9IJeQ==", - "license": "MIT", - "dependencies": { - "@shinyoshiaki/jspack": "^0.0.6", - "debug": "^4.4.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/werift-dtls": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/werift-dtls/-/werift-dtls-0.5.7.tgz", - "integrity": "sha512-z2fjbP7fFUFmu/Ky4bCKXzdgPTtmSY1DYi0TUf3GG2zJT4jMQ3TQmGY8y7BSSNGetvL4h3pRZ5un0EcSOWpPog==", - "license": "MIT", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@noble/curves": "^1.3.0", - "@peculiar/x509": "^1.9.2", - "@shinyoshiaki/binary-data": "^0.6.1", - "date-fns": "^2.29.3", - "lodash": "^4.17.21", - "rx.mini": "^1.2.2", "tweetnacl": "^1.0.3" }, "engines": { "node": ">=16" } }, - "node_modules/werift-ice": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/werift-ice/-/werift-ice-0.2.2.tgz", - "integrity": "sha512-td52pHp+JmFnUn5jfDr/SSNO0dMCbknhuPdN1tFp9cfRj5jaktN63qnAdUuZC20QCC3ETWdsOthcm+RalHpFCQ==", - "license": "MIT", - "dependencies": { - "@shinyoshiaki/jspack": "^0.0.6", - "buffer-crc32": "^1.0.0", - "debug": "^4.3.4", - "int64-buffer": "^1.0.1", - "ip": "^2.0.1", - "lodash": "^4.17.21", - "multicast-dns": "^7.2.5", - "p-cancelable": "^2.1.1", - "rx.mini": "^1.2.2" - } - }, - "node_modules/werift-rtp": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/werift-rtp/-/werift-rtp-0.8.8.tgz", - "integrity": "sha512-GiYMSdvCyScQaw5bnEsraSoHUVZpjfokJAiLV4R1FsiB06t6XiebPYPpkqB9nYNNKiA8Z/cYWsym7wISq1sYSQ==", - "license": "MIT", - "dependencies": { - "@minhducsun2002/leb128": "^1.0.0", - "@shinyoshiaki/jspack": "^0.0.6", - "aes-js": "^3.1.2", - "buffer": "^6.0.3", - "mp4box": "^0.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/werift-rtp/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/werift-sctp": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/werift-sctp/-/werift-sctp-0.0.11.tgz", - "integrity": "sha512-7109yuI5U7NTEHjqjn0A8VeynytkgVaxM6lRr1Ziv0D8bPcaB8A7U/P88M7WaCpWDoELHoXiRUjQycMWStIgjQ==", - "license": "MIT", - "dependencies": { - "@shinyoshiaki/jspack": "^0.0.6" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/werift/node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -15938,7 +15813,7 @@ "pouchdb-replication": "^9.0.0", "pouchdb-utils": "^9.0.0", "transform-pouch": "^2.0.0", - "werift": "^0.23.0" + "werift": "^0.24.4" }, "devDependencies": { "typescript": "5.9.3", diff --git a/src/apps/cli/package.json b/src/apps/cli/package.json index caf1143b..7bb12afc 100644 --- a/src/apps/cli/package.json +++ b/src/apps/cli/package.json @@ -48,7 +48,7 @@ "pouchdb-replication": "^9.0.0", "pouchdb-utils": "^9.0.0", "transform-pouch": "^2.0.0", - "werift": "^0.23.0" + "werift": "^0.24.4" }, "devDependencies": { "typescript": "5.9.3", diff --git a/src/common/compatibilitySettings.ts b/src/common/compatibilitySettings.ts new file mode 100644 index 00000000..5197ade5 --- /dev/null +++ b/src/common/compatibilitySettings.ts @@ -0,0 +1,32 @@ +type LegacyLocalDatabaseSelection = { + useIndexedDBAdapter: boolean; +}; + +type LegacyBulkChunkPreSendSettings = { + sendChunksBulk: boolean; + sendChunksBulkMaxSize: number; +}; + +/** + * Returns whether persisted settings select the legacy PouchDB IndexedDB adapter. + * + * New local databases use IDB. Existing devices must retain this operative value until their local database has + * been explicitly migrated, so compatibility code must not treat the setting as inert. + */ +export function usesLegacyIndexedDBAdapter(settings: LegacyLocalDatabaseSelection): boolean { + return settings.useIndexedDBAdapter; +} + +/** + * Disables the removed automatic bulk chunk pre-send option in persisted settings. + * + * The field remains readable only so older settings and Setup URIs can be migrated to the supported behaviour. + * + * @returns `true` when the legacy setting was enabled and has been changed. + */ +export function disableLegacyBulkChunkPreSend(settings: LegacyBulkChunkPreSendSettings): boolean { + if (!settings.sendChunksBulk) return false; + settings.sendChunksBulk = false; + settings.sendChunksBulkMaxSize = 1; + return true; +} diff --git a/src/common/compatibilitySettings.unit.spec.ts b/src/common/compatibilitySettings.unit.spec.ts new file mode 100644 index 00000000..8482ff56 --- /dev/null +++ b/src/common/compatibilitySettings.unit.spec.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from "vitest"; +import { disableLegacyBulkChunkPreSend, usesLegacyIndexedDBAdapter } from "./compatibilitySettings.ts"; + +describe("compatibility settings", () => { + it.each([true, false])("preserves the operative legacy adapter selection (%s)", (useIndexedDBAdapter) => { + expect(usesLegacyIndexedDBAdapter({ useIndexedDBAdapter })).toBe(useIndexedDBAdapter); + }); + + it("disables automatic bulk chunk pre-send and restores its inert size value", () => { + const settings = { sendChunksBulk: true, sendChunksBulkMaxSize: 16 }; + + expect(disableLegacyBulkChunkPreSend(settings)).toBe(true); + expect(settings).toEqual({ sendChunksBulk: false, sendChunksBulkMaxSize: 1 }); + }); + + it("leaves an already migrated bulk chunk setting unchanged", () => { + const settings = { sendChunksBulk: false, sendChunksBulkMaxSize: 4 }; + + expect(disableLegacyBulkChunkPreSend(settings)).toBe(false); + expect(settings).toEqual({ sendChunksBulk: false, sendChunksBulkMaxSize: 4 }); + }); +}); diff --git a/src/modules/core/ModuleReplicator.ts b/src/modules/core/ModuleReplicator.ts index f7aed4cc..4d2b352a 100644 --- a/src/modules/core/ModuleReplicator.ts +++ b/src/modules/core/ModuleReplicator.ts @@ -22,6 +22,7 @@ import { UnresolvedErrorManager } from "@vrtmrz/livesync-commonlib/compat/servic import { clearHandlers } from "@vrtmrz/livesync-commonlib/compat/replication/SyncParamsHandler"; import type { NecessaryServices } from "@vrtmrz/livesync-commonlib/compat/interfaces/ServiceModule"; import { MARK_LOG_NETWORK_ERROR } from "@vrtmrz/livesync-commonlib/compat/services/lib/logUtils"; +import { usesLegacyIndexedDBAdapter } from "@/common/compatibilitySettings.ts"; function isOnlineAndCanReplicate( errorManager: UnresolvedErrorManager, @@ -145,10 +146,12 @@ export class ModuleReplicator extends AbstractModule { } /** - * Reconciles local chunks when an older IndexedDB client reports that the remote database was cleaned. - * This compatibility path remains reachable while those clients can still set `remoteCleaned`. - * @deprecated v0.24.17 - * @param showMessage If true, show message to the user. + * Reconciles an IndexedDB-backed local database after replication reports that the remote was cleaned. + * + * The remote milestone remains a supported compatibility signal. The user can either fetch the remote + * database again, or purge unreferenced local chunks before accepting this device again. + * + * @param showMessage Whether to show the recovery choices as user-facing notices. */ async cleaned(showMessage: boolean) { Logger(`The remote database has been cleaned.`, showMessage ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO); @@ -230,7 +233,7 @@ Even if you choose to clean up, you will see this option again if you exit Obsid await this.services.tweakValue.askResolvingMismatched(activeReplicator.preferredTweakValue); } else { if (activeReplicator.remoteLockedAndDeviceNotAccepted) { - if (activeReplicator.remoteCleaned && this.settings.useIndexedDBAdapter) { + if (activeReplicator.remoteCleaned && usesLegacyIndexedDBAdapter(this.settings)) { await this.cleaned(showMessage); } else { const message = $msg("Replicator.Dialogue.Locked.Message"); diff --git a/src/modules/essential/ModuleMigration.ts b/src/modules/essential/ModuleMigration.ts index 38d34805..a878c301 100644 --- a/src/modules/essential/ModuleMigration.ts +++ b/src/modules/essential/ModuleMigration.ts @@ -24,6 +24,7 @@ import { runConfiguredStartupLifecycle, runStartupEntryLifecycle, } from "@/serviceFeatures/configuredStartupLifecycle.ts"; +import { disableLegacyBulkChunkPreSend } from "@/common/compatibilitySettings.ts"; type ErrorInfo = { path: string; @@ -77,10 +78,8 @@ export class ModuleMigration extends AbstractModule { } async migrateDisableBulkSend() { - if (this.settings.sendChunksBulk) { + if (disableLegacyBulkChunkPreSend(this.settings)) { this._log($msg("moduleMigration.logBulkSendCorrupted"), LOG_LEVEL_NOTICE); - this.settings.sendChunksBulk = false; - this.settings.sendChunksBulkMaxSize = 1; await this.saveSettings(); } } diff --git a/src/modules/essential/ModuleMigration.unit.spec.ts b/src/modules/essential/ModuleMigration.unit.spec.ts index b51665c7..5e2f3e99 100644 --- a/src/modules/essential/ModuleMigration.unit.spec.ts +++ b/src/modules/essential/ModuleMigration.unit.spec.ts @@ -18,7 +18,10 @@ async function* failedDocumentScan() { throw new Error("scan failed"); } -function createMigration(findAllNormalDocs: typeof noDocuments | typeof failedDocumentScan = noDocuments) { +function createMigration( + findAllNormalDocs: typeof noDocuments | typeof failedDocumentScan = noDocuments, + settings = { sendChunksBulk: false, sendChunksBulkMaxSize: 1 } +) { const noticeGroups = { setItem: vi.fn(), finish: vi.fn(() => true), @@ -32,6 +35,7 @@ function createMigration(findAllNormalDocs: typeof noDocuments | typeof failedDo registerProtocolHandler: vi.fn(), }, context: { noticeGroups }, + setting: { saveSettingData: vi.fn(async () => undefined) }, vault: { isTargetFile: vi.fn(async () => true) }, path: { getPath: vi.fn() }, }; @@ -44,13 +48,37 @@ function createMigration(findAllNormalDocs: typeof noDocuments | typeof failedDo }, localDatabase: { findAllNormalDocs }, storageAccess: {}, + settings, }; return { migration: new ModuleMigration(core as never), noticeGroups, + saveSettingData: services.setting.saveSettingData, }; } +describe("ModuleMigration obsolete-setting migration", () => { + it("persists the removal of an enabled automatic bulk chunk pre-send setting", async () => { + const settings = { sendChunksBulk: true, sendChunksBulkMaxSize: 16 }; + const { migration, saveSettingData } = createMigration(noDocuments, settings); + + await migration.migrateDisableBulkSend(); + + expect(settings).toEqual({ sendChunksBulk: false, sendChunksBulkMaxSize: 1 }); + expect(saveSettingData).toHaveBeenCalledOnce(); + }); + + it("does not persist an already disabled automatic bulk chunk pre-send setting", async () => { + const settings = { sendChunksBulk: false, sendChunksBulkMaxSize: 16 }; + const { migration, saveSettingData } = createMigration(noDocuments, settings); + + await migration.migrateDisableBulkSend(); + + expect(settings).toEqual({ sendChunksBulk: false, sendChunksBulkMaxSize: 16 }); + expect(saveSettingData).not.toHaveBeenCalled(); + }); +}); + describe("ModuleMigration incomplete-document notice", () => { it("keeps the check and its result in one persistent named group", async () => { const { migration, noticeGroups } = createMigration(); diff --git a/src/modules/extras/ModuleDev.ts b/src/modules/extras/ModuleDev.ts index b74b94ec..0a03db8d 100644 --- a/src/modules/extras/ModuleDev.ts +++ b/src/modules/extras/ModuleDev.ts @@ -2,12 +2,9 @@ import { delay } from "octagonal-wheels/promises"; import { __onMissingTranslation } from "@/common/translation"; import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts"; import { LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger"; -// import { enableTestFunction } from "./devUtil/testUtils.ts"; -import { TestPaneView, VIEW_TYPE_TEST } from "./devUtil/TestPaneView.ts"; import { writable } from "svelte/store"; import type { FilePathWithPrefix } from "@vrtmrz/livesync-commonlib/compat/common/types"; import type { LiveSyncCore } from "@/main.ts"; -import type { WorkspaceLeaf } from "@/deps.ts"; export class ModuleDev extends AbstractObsidianModule { _everyOnloadStart(): Promise { __onMissingTranslation(() => {}); @@ -35,25 +32,8 @@ export class ModuleDev extends AbstractObsidianModule { } } - private _everyOnloadAfterLoadSettings(): Promise { - if (!this.settings.enableDebugTools) return Promise.resolve(true); - this.registerView(VIEW_TYPE_TEST, (leaf: WorkspaceLeaf) => new TestPaneView(leaf, this.plugin, this)); - this.addCommand({ - id: "view-test", - name: "Open Test dialogue", - callback: () => { - void this.services.API.showWindow(VIEW_TYPE_TEST); - }, - }); - return Promise.resolve(true); - } - async _everyOnLayoutReady(): Promise { if (!this.settings.enableDebugTools) return Promise.resolve(true); - // if (await this.core.storageAccess.isExistsIncludeHidden("_SHOWDIALOGAUTO.md")) { - // void this.core.$$showView(VIEW_TYPE_TEST); - // } - this.addCommand({ id: "test-create-conflict", name: "Create conflict", @@ -110,7 +90,6 @@ export class ModuleDev extends AbstractObsidianModule { override onBindFunction(core: LiveSyncCore, services: typeof core.services): void { services.appLifecycle.onLayoutReady.addHandler(this._everyOnLayoutReady.bind(this)); services.appLifecycle.onInitialise.addHandler(this._everyOnloadStart.bind(this)); - services.appLifecycle.onSettingLoaded.addHandler(this._everyOnloadAfterLoadSettings.bind(this)); services.test.test.addHandler(this._everyModuleTest.bind(this)); services.test.addTestResult.setHandler(this._addTestResult.bind(this)); } diff --git a/src/modules/extras/devUtil/TestPane.svelte b/src/modules/extras/devUtil/TestPane.svelte deleted file mode 100644 index 09918409..00000000 --- a/src/modules/extras/devUtil/TestPane.svelte +++ /dev/null @@ -1,118 +0,0 @@ - - -

TESTING BENCH: Self-hosted LiveSync

- -

Module Checks

- - - - - -{#each resultLines as [result, line, message]} -
- [{result ? "PASS" : "FAILED"}] {line} -
{message}
-
-{/each} - -

Synchronisation Result Status

-
{syncStatus.join("\n")}
- -

Performance test

- - - -
- - diff --git a/src/modules/extras/devUtil/TestPaneView.ts b/src/modules/extras/devUtil/TestPaneView.ts deleted file mode 100644 index 56c81772..00000000 --- a/src/modules/extras/devUtil/TestPaneView.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ItemView, WorkspaceLeaf } from "@/deps.ts"; -import TestPaneComponent from "./TestPane.svelte"; -import type ObsidianLiveSyncPlugin from "@/main.ts"; -import type { ModuleDev } from "@/modules/extras/ModuleDev.ts"; -export const VIEW_TYPE_TEST = "ols-pane-test"; -declare global { - interface LSEvents { - "debug-sync-status": string[]; - } -} -//Log view -export class TestPaneView extends ItemView { - component?: TestPaneComponent; - plugin: ObsidianLiveSyncPlugin; - moduleDev: ModuleDev; - override icon = "view-log"; - title: string = "Self-hosted LiveSync Test and Results"; - override navigation = true; - - override getIcon(): string { - return "view-log"; - } - - constructor(leaf: WorkspaceLeaf, plugin: ObsidianLiveSyncPlugin, moduleDev: ModuleDev) { - super(leaf); - this.plugin = plugin; - this.moduleDev = moduleDev; - } - - getViewType() { - return VIEW_TYPE_TEST; - } - - getDisplayText() { - return "Self-hosted LiveSync Test and Results"; - } - - override async onOpen() { - this.component = new TestPaneComponent({ - target: this.contentEl, - props: { - plugin: this.plugin, - moduleDev: this.moduleDev, - }, - }); - await Promise.resolve(); - } - - override async onClose() { - this.component?.$destroy(); - await Promise.resolve(); - } -} diff --git a/src/modules/extras/devUtil/tests.ts b/src/modules/extras/devUtil/tests.ts deleted file mode 100644 index 60e3ec0d..00000000 --- a/src/modules/extras/devUtil/tests.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Trench } from "octagonal-wheels/memory/memutil"; -import type ObsidianLiveSyncPlugin from "@/main.ts"; -type MeasureResult = [times: number, spent: number]; -type NamedMeasureResult = [name: string, result: MeasureResult]; -const measures = new Map(); - -function clearResult(name: string) { - measures.set(name, [0, 0]); -} -async function measureEach(name: string, proc: () => void | Promise) { - const [times, spent] = measures.get(name) ?? [0, 0]; - - const start = performance.now(); - const result = proc(); - if (result instanceof Promise) await result; - const end = performance.now(); - measures.set(name, [times + 1, spent + (end - start)]); -} -function formatNumber(num: number) { - return num.toLocaleString("en-US", { maximumFractionDigits: 2 }); -} -async function measure( - name: string, - proc: () => void | Promise, - times: number = 10000, - duration: number = 1000 -): Promise { - const from = Date.now(); - let last = times; - clearResult(name); - do { - await measureEach(name, proc); - } while (last-- > 0 && Date.now() - from < duration); - return [name, measures.get(name) as MeasureResult]; -} - -function formatPerfResults(items: NamedMeasureResult[]) { - return ( - `| Name | Runs | Each | Total |\n| --- | --- | --- | --- | \n` + - items - .map( - (e) => - `| ${e[0]} | ${e[1][0]} | ${e[1][0] != 0 ? formatNumber(e[1][1] / e[1][0]) : "-"} | ${formatNumber(e[1][0])} |` - ) - .join("\n") - ); -} -export async function perf_trench(plugin: ObsidianLiveSyncPlugin) { - clearResult("trench"); - const trench = new Trench(plugin.core.simpleStore); - const result = [] as NamedMeasureResult[]; - result.push( - await measure("trench-short-string", async () => { - const p = trench.evacuate("string"); - await p(); - }) - ); - { - const testBinary = await plugin.core.storageAccess.readHiddenFileBinary("testdata/10kb.png"); - const uint8Array = new Uint8Array(testBinary); - result.push( - await measure("trench-binary-10kb", async () => { - const p = trench.evacuate(uint8Array); - await p(); - }) - ); - } - { - const testBinary = await plugin.core.storageAccess.readHiddenFileBinary("testdata/100kb.jpeg"); - const uint8Array = new Uint8Array(testBinary); - result.push( - await measure("trench-binary-100kb", async () => { - const p = trench.evacuate(uint8Array); - await p(); - }) - ); - } - { - const testBinary = await plugin.core.storageAccess.readHiddenFileBinary("testdata/1mb.png"); - const uint8Array = new Uint8Array(testBinary); - result.push( - await measure("trench-binary-1mb", async () => { - const p = trench.evacuate(uint8Array); - await p(); - }) - ); - } - return formatPerfResults(result); -} diff --git a/src/modules/features/SettingDialogue/PanePatches.ts b/src/modules/features/SettingDialogue/PanePatches.ts index 1117b0eb..1816d6d5 100644 --- a/src/modules/features/SettingDialogue/PanePatches.ts +++ b/src/modules/features/SettingDialogue/PanePatches.ts @@ -13,6 +13,7 @@ import { visibleOnly } from "./SettingPane.ts"; import { PouchDB } from "@vrtmrz/livesync-commonlib/compat/pouchdb/pouchdb-browser"; import { ExtraSuffixIndexedDB } from "@vrtmrz/livesync-commonlib/compat/common/types"; import { migrateDatabases } from "./settingUtils.ts"; +import { usesLegacyIndexedDBAdapter } from "@/common/compatibilitySettings.ts"; export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void { void addPanel(paneEl, "Compatibility (Metadata)").then((paneEl) => { @@ -74,7 +75,8 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen } }; { - const infoClass = this.editingSettings.useIndexedDBAdapter ? "op-warn" : "op-warn-info"; + const useIndexedDBAdapter = usesLegacyIndexedDBAdapter(this.editingSettings); + const infoClass = useIndexedDBAdapter ? "op-warn" : "op-warn-info"; paneEl.createDiv({ text: "The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.", cls: infoClass, @@ -87,8 +89,8 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen .setName("Database Adapter") .setDesc("Select the database adapter to use. "); const el = setting.controlEl.createDiv({}); - el.setText(`Current adapter: ${this.editingSettings.useIndexedDBAdapter ? "IndexedDB" : "IDB"}`); - if (!this.editingSettings.useIndexedDBAdapter) { + el.setText(`Current adapter: ${useIndexedDBAdapter ? "IndexedDB" : "IDB"}`); + if (!useIndexedDBAdapter) { setting.addButton((button) => { button.setButtonText("Switch to IndexedDB").onClick(async () => { Logger("Migrating all data to IndexedDB...", LOG_LEVEL_NOTICE);