mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-06-10 00:10:13 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| caaff618e9 | |||
| 148aa8505e | |||
| f9a626a858 | |||
| e739302fb9 | |||
| 8f20d53f55 | |||
| fd84b0377b | |||
| 340d416b76 | |||
| 3034af8d69 | |||
| da3020bd45 |
@@ -9,6 +9,10 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -29,68 +33,20 @@ jobs:
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
# Attest
|
||||
- name: Attest Plugin Artifacts
|
||||
uses: actions/attest-build-provenance@v4
|
||||
with:
|
||||
subject-path: |
|
||||
main.js
|
||||
manifest.json
|
||||
styles.css
|
||||
# Package the required files into a zip
|
||||
- name: Package
|
||||
run: |
|
||||
mkdir ${{ github.event.repository.name }}
|
||||
cp main.js manifest.json styles.css README.md ${{ github.event.repository.name }}
|
||||
zip -r ${{ github.event.repository.name }}.zip ${{ github.event.repository.name }}
|
||||
# Create the release on github
|
||||
# - name: Create Release
|
||||
# id: create_release
|
||||
# uses: actions/create-release@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# VERSION: ${{ steps.version.outputs.tag }}
|
||||
# with:
|
||||
# tag_name: ${{ steps.version.outputs.tag }}
|
||||
# release_name: ${{ steps.version.outputs.tag }}
|
||||
# draft: true
|
||||
# prerelease: false
|
||||
# # Upload the packaged release file
|
||||
# - name: Upload zip file
|
||||
# id: upload-zip
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
# asset_path: ./${{ github.event.repository.name }}.zip
|
||||
# asset_name: ${{ github.event.repository.name }}-${{ steps.version.outputs.tag }}.zip
|
||||
# asset_content_type: application/zip
|
||||
# # Upload the main.js
|
||||
# - name: Upload main.js
|
||||
# id: upload-main
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
# asset_path: ./main.js
|
||||
# asset_name: main.js
|
||||
# asset_content_type: text/javascript
|
||||
# # Upload the manifest.json
|
||||
# - name: Upload manifest.json
|
||||
# id: upload-manifest
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
# asset_path: ./manifest.json
|
||||
# asset_name: manifest.json
|
||||
# asset_content_type: application/json
|
||||
# # Upload the style.css
|
||||
# - name: Upload styles.css
|
||||
# id: upload-css
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
# asset_path: ./styles.css
|
||||
# asset_name: styles.css
|
||||
# asset_content_type: text/css
|
||||
- name: Create Release and Upload Assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
|
||||
@@ -10,7 +10,18 @@ on:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'test/**'
|
||||
- 'lib/**'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'tsconfig.json'
|
||||
- 'vite.config.ts'
|
||||
- 'vitest.config*.ts'
|
||||
- 'esbuild.config.mjs'
|
||||
- 'eslint.config.mjs'
|
||||
- '.github/workflows/unit-ci.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'test/**'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'tsconfig.json'
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "0.25.66",
|
||||
"version": "0.25.69",
|
||||
"minAppVersion": "1.7.2",
|
||||
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"author": "vorotamoroz",
|
||||
"authorUrl": "https://github.com/vrtmrz",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
}
|
||||
Generated
+18
-18
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.66",
|
||||
"version": "0.25.69",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.66",
|
||||
"version": "0.25.69",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.808.0",
|
||||
@@ -15,7 +15,7 @@
|
||||
"@smithy/middleware-apply-body-checksum": "^4.3.9",
|
||||
"@smithy/protocol-http": "^5.3.9",
|
||||
"@smithy/querystring-builder": "^4.2.9",
|
||||
"@trystero-p2p/nostr": "^0.23.0",
|
||||
"@trystero-p2p/nostr": "^0.24.0",
|
||||
"chokidar": "^4.0.0",
|
||||
"commander": "^14.0.3",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
@@ -28,7 +28,7 @@
|
||||
"octagonal-wheels": "^0.1.45",
|
||||
"pouchdb-adapter-leveldb": "^9.0.0",
|
||||
"qrcode-generator": "^1.4.4",
|
||||
"werift": "^0.22.9",
|
||||
"werift": "^0.23.0",
|
||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -2684,9 +2684,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/secp256k1": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-3.0.0.tgz",
|
||||
"integrity": "sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-3.1.0.tgz",
|
||||
"integrity": "sha512-+F7iS7tUMaNGXcc9X3PjmjvuQnXEuSjCRNzVVA2xAcKXgCaP0dHYz4SFyt4FKNHef7sOP//xihowcySSS7PK9g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
@@ -4297,19 +4297,19 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@trystero-p2p/core": {
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@trystero-p2p/core/-/core-0.23.0.tgz",
|
||||
"integrity": "sha512-ozhtgxKDZH11Gdef0wH8xivwAE/L0/lDFvEcNFWPJWnHZlxWPPyfeonwE287ssGevQNi10vnj6x2ZcOi0n1bQQ==",
|
||||
"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.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@trystero-p2p/nostr/-/nostr-0.23.0.tgz",
|
||||
"integrity": "sha512-KSqUR2c1KVfv4zeErcntuegtyKzFTzNNiitIKGD0LiKA/4H3CeTF81ROk2h+X/PNvP4mv7Gp5eVxFYwfMu4Nrg==",
|
||||
"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.0.0",
|
||||
"@trystero-p2p/core": "0.23.0"
|
||||
"@noble/secp256k1": "^3.1.0",
|
||||
"@trystero-p2p/core": "0.24.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/svelte": {
|
||||
@@ -16291,9 +16291,9 @@
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/werift": {
|
||||
"version": "0.22.9",
|
||||
"resolved": "https://registry.npmjs.org/werift/-/werift-0.22.9.tgz",
|
||||
"integrity": "sha512-TE9AxskSRWBMYm0MBRllfnKVXQelqC76JCvyolQyVWpmKabfY5BA/cuvkGg+71JWn3QrGih1YWtpIWGPqoxcoA==",
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmjs.org/werift/-/werift-0.23.0.tgz",
|
||||
"integrity": "sha512-/WcIN5DHFG9Ri4anGOmIkp8gxBGFMWSIB/m4sfZ5CWlLfD3iMhiaAUuTBuc+KV3SY9NDmvmLtiN2uaM7k3lVzw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fidm/x509": "^1.2.1",
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.66",
|
||||
"version": "0.25.69",
|
||||
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"main": "main.js",
|
||||
"type": "module",
|
||||
@@ -130,7 +130,7 @@
|
||||
"@smithy/middleware-apply-body-checksum": "^4.3.9",
|
||||
"@smithy/protocol-http": "^5.3.9",
|
||||
"@smithy/querystring-builder": "^4.2.9",
|
||||
"@trystero-p2p/nostr": "^0.23.0",
|
||||
"@trystero-p2p/nostr": "^0.24.0",
|
||||
"chokidar": "^4.0.0",
|
||||
"commander": "^14.0.3",
|
||||
"obsidian": "^1.12.3",
|
||||
@@ -143,7 +143,7 @@
|
||||
"octagonal-wheels": "^0.1.45",
|
||||
"pouchdb-adapter-leveldb": "^9.0.0",
|
||||
"qrcode-generator": "^1.4.4",
|
||||
"werift": "^0.22.9",
|
||||
"werift": "^0.23.0",
|
||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
let serverInfo = $state<P2PServerInfo | undefined>(undefined);
|
||||
let replicatorStatus = $state<P2PReplicatorStatus | undefined>(undefined);
|
||||
let roomSuffix = $state<string>(extractP2PRoomSuffix(core?.services.setting.currentSettings()?.P2P_roomID ?? ""));
|
||||
let useDiagRTC = $state<boolean>(core?.services.setting.currentSettings()?.P2P_useDiagRTC ?? false);
|
||||
|
||||
async function requestServerStatus() {
|
||||
await Promise.resolve(liveSyncReplicator.requestStatus());
|
||||
@@ -48,6 +49,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleDiagRTC() {
|
||||
if (!core) {
|
||||
return;
|
||||
}
|
||||
const next = !useDiagRTC;
|
||||
await core.services.setting.updateSettings((settings) => {
|
||||
settings.P2P_useDiagRTC = next;
|
||||
return settings;
|
||||
}, true);
|
||||
useDiagRTC = next;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribe = eventHub.onEvent(EVENT_SERVER_STATUS, (status) => {
|
||||
serverInfo = status;
|
||||
@@ -58,6 +71,7 @@
|
||||
});
|
||||
const unsubscribeSettings = eventHub.onEvent(EVENT_SETTING_SAVED, (settings) => {
|
||||
roomSuffix = extractP2PRoomSuffix(settings?.P2P_roomID ?? "");
|
||||
useDiagRTC = settings?.P2P_useDiagRTC ?? false;
|
||||
});
|
||||
|
||||
fireAndForget(async () => {
|
||||
@@ -131,6 +145,48 @@
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if core}
|
||||
<div class="status-item status-action diag-toggle-row">
|
||||
<label class="broadcast-label" for="diag-toggle">
|
||||
🕵️ Diag
|
||||
</label>
|
||||
<button
|
||||
id="diag-toggle"
|
||||
class="broadcast-button {useDiagRTC ? 'is-on' : 'is-off'}"
|
||||
onclick={toggleDiagRTC}
|
||||
title={useDiagRTC
|
||||
? 'Diagnostic RTCPeerConnection is enabled'
|
||||
: 'Use Diagnostic RTCPeerConnection for statistics'}
|
||||
>
|
||||
{useDiagRTC ? 'On' : 'Off'}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if serverInfo}
|
||||
<div class="diag-section">
|
||||
<h4>Stats</h4>
|
||||
<div class="diag-grid">
|
||||
<div class="diag-item">
|
||||
<span>Incoming:</span>
|
||||
<span>{serverInfo.diag.totalNewConnections}</span>
|
||||
</div>
|
||||
<div class="diag-item">
|
||||
<span>Connected:</span>
|
||||
<span>{serverInfo.diag.totalSuccessfulConnections}</span>
|
||||
</div>
|
||||
<div class="diag-item">
|
||||
<span>Failed:</span>
|
||||
<span>{serverInfo.diag.totalFailedConnections}</span>
|
||||
</div>
|
||||
<div class="diag-item">
|
||||
<span>Closed:</span>
|
||||
<span>{serverInfo.diag.totalClosedConnections}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -190,6 +246,11 @@
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.diag-toggle-row {
|
||||
align-items: center;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.broadcast-label {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-normal);
|
||||
@@ -221,4 +282,29 @@
|
||||
background-color: var(--interactive-hover);
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.diag-section {
|
||||
border-top: 1px solid var(--divider-color);
|
||||
margin-top: 0.75rem;
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.diag-section h4 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.diag-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
|
||||
gap: 0.35rem 0.75rem;
|
||||
}
|
||||
|
||||
.diag-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.85rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
+1
-1
Submodule src/lib updated: c5beaa3866...e97ca5821c
@@ -128,7 +128,7 @@ export class ModuleResolvingMismatchedTweaks extends AbstractModule {
|
||||
}
|
||||
|
||||
async _checkAndAskResolvingMismatchedTweaks(preferred: TweakValues): Promise<[TweakValues | boolean, boolean]> {
|
||||
const mine = extractObject(TweakValuesShouldMatchedTemplate, this.settings) as TweakValues;
|
||||
const mine = extractObject(TweakValuesTemplate, this.settings) as TweakValues;
|
||||
const mismatchedKeys = this._collectMismatchedTweakKeys(mine, preferred);
|
||||
const autoAcceptSide = await this._shouldAutoAcceptCompatibleLossy(mine, preferred, mismatchedKeys);
|
||||
if (autoAcceptSide === "REMOTE") {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
REMOTE_MINIO,
|
||||
REMOTE_P2P,
|
||||
} from "../../lib/src/common/types.ts";
|
||||
import { generatePatchObj, isObjectDifferent } from "../../lib/src/common/utils.ts";
|
||||
import { isObjectDifferent } from "@lib/common/utils.ts";
|
||||
import Intro from "./SetupWizard/dialogs/Intro.svelte";
|
||||
import SelectMethodNewUser from "./SetupWizard/dialogs/SelectMethodNewUser.svelte";
|
||||
import SelectMethodExisting from "./SetupWizard/dialogs/SelectMethodExisting.svelte";
|
||||
@@ -23,6 +23,7 @@ import SetupRemoteP2P from "./SetupWizard/dialogs/SetupRemoteP2P.svelte";
|
||||
import SetupRemoteE2EE from "./SetupWizard/dialogs/SetupRemoteE2EE.svelte";
|
||||
import { decodeSettingsFromQRCodeData } from "../../lib/src/API/processSetting.ts";
|
||||
import { AbstractModule } from "../AbstractModule.ts";
|
||||
import { ConnectionStringParser } from "@lib/common/ConnectionString.ts";
|
||||
|
||||
/**
|
||||
* User modes for onboarding and setup
|
||||
@@ -194,8 +195,24 @@ export class SetupManager extends AbstractModule {
|
||||
return await this.onOnboard(userMode);
|
||||
}
|
||||
const newSetting = { ...currentSetting, ...p2pConf } as ObsidianLiveSyncSettings;
|
||||
// Apply remoteConfigurations
|
||||
if (newSetting.P2P_ActiveRemoteConfigurationId) {
|
||||
const id = newSetting.P2P_ActiveRemoteConfigurationId;
|
||||
const merged = {
|
||||
...newSetting,
|
||||
...p2pConf,
|
||||
} as ObsidianLiveSyncSettings;
|
||||
const uri = ConnectionStringParser.serialize({ type: "p2p", settings: merged });
|
||||
newSetting.remoteConfigurations[id] = {
|
||||
...newSetting.remoteConfigurations[id],
|
||||
uri,
|
||||
isEncrypted: false,
|
||||
};
|
||||
newSetting.P2P_ActiveRemoteConfigurationId = id;
|
||||
}
|
||||
if (activate) {
|
||||
newSetting.remoteType = REMOTE_P2P;
|
||||
newSetting.activeConfigurationId = newSetting.P2P_ActiveRemoteConfigurationId;
|
||||
}
|
||||
return await this.onConfirmApplySettingsFromWizard(newSetting, userMode, activate);
|
||||
}
|
||||
@@ -285,9 +302,9 @@ export class SetupManager extends AbstractModule {
|
||||
this._log("No changes in settings detected. Skipping applying settings from wizard.", LOG_LEVEL_NOTICE);
|
||||
return true;
|
||||
}
|
||||
const patch = generatePatchObj(this.settings, newConf);
|
||||
console.log(`Changes:`);
|
||||
console.dir(patch);
|
||||
// const patch = generatePatchObj(this.settings, newConf);
|
||||
// console.log(`Changes:`);
|
||||
// console.dir(patch);
|
||||
if (!activate) {
|
||||
extra();
|
||||
await this.applySetting(newConf, UserMode.ExistingUser);
|
||||
|
||||
+2
-2
@@ -34,11 +34,11 @@ const terserOption = {
|
||||
inline: false,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
passes: 4,
|
||||
passes: 1,
|
||||
reduce_vars: true,
|
||||
reduce_funcs: false,
|
||||
arrows: true,
|
||||
collapse_vars: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
//@ts-ignore
|
||||
lhs_constants: true,
|
||||
|
||||
+27
-1
@@ -3,7 +3,33 @@ Since 19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
|
||||
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.
|
||||
|
||||
## 0.25.66
|
||||
## 0.25.69
|
||||
|
||||
22nd May, 2026
|
||||
|
||||
### Fixed
|
||||
- No longer does the P2P passphrase mismatch cause a server shutdown.
|
||||
- Settings related to P2P synchronisation are now correctly applied on start-up and no longer reverted.
|
||||
|
||||
### New features
|
||||
- Diagnostic P2P connection stats are now available.
|
||||
- These stats indicate the number of connection trials, successes, and failures.
|
||||
|
||||
## 0.25.68
|
||||
|
||||
22nd May, 2026
|
||||
|
||||
### Improved
|
||||
|
||||
- P2P connections have improved slightly
|
||||
- Upgrade to `trystero` v0.24.0, and fixes event handler assignment. This should fix some edge cases where P2P connections fail to establish or messages are not properly handled.
|
||||
- Weaken terser options to avoid potential issues with minification that could cause runtime errors in some environments.
|
||||
|
||||
## ~~0.25.66~~ 0.25.67
|
||||
|
||||
20th May, 2026
|
||||
|
||||
0.25.66 had a bug that the auto-accept logic for compatible but lossy mismatches was not working as intended.
|
||||
|
||||
### New features
|
||||
- Implement an auto-accept compatible tweak setting and enhance the mismatch resolution logic.
|
||||
|
||||
Reference in New Issue
Block a user