Compare commits

...

9 Commits

Author SHA1 Message Date
vorotamoroz
16c6c52128 bump 2024-06-04 11:35:36 +01:00
vorotamoroz
8b94a0b72e Fixed:
- No longer files have been trimmed even delimiters have been continuous.
- Fixed the toggle title to `Do not split chunks in the background` from `Do not split chunks in the foreground`.
- Non-configured item mismatches are no longer detected.
2024-06-04 11:34:42 +01:00
vorotamoroz
c5ac76d916 bump 2024-05-30 10:53:48 +01:00
vorotamoroz
b67a6db8a1 Improved:
- Now notes will be split into chunks in the background thread to improve smoothness.
  - Default enabled, to disable, toggle `Do not split chunks in the foreground` on `Hatch` -> `Compatibility`.
  - If you want to process very small notes in the foreground, please enable `Process small files in the foreground` on `Hatch` -> `Compatibility`.
- We can use a `splitting-limit-capped chunk splitter`; which performs more simple and make less amount of chunks.
  - Default disabled, to enable, toggle `Use splitting-limit-capped chunk splitter` on `Sync settings` -> `Performance tweaks`
Tidied
  - Some files have been separated into multiple files to make them more explicit in what they are responsible for.
2024-05-30 10:52:20 +01:00
vorotamoroz
d4202161e8 bump 2024-05-28 12:27:30 +01:00
vorotamoroz
2a2b39009c Fixed:
- Now we *surely* can set the device name and enable customised synchronisation.
- Unnecessary dialogue update processes have been eliminated.
- Customisation sync no longer stores half-collected files.
- No longer hangs up when removing or renaming files with the `Sync on Save` toggle enabled.
Improved:
- Customisation sync now performs data deserialization more smoothly.
- New translations have been merged.
2024-05-28 12:26:23 +01:00
vorotamoroz
bf3a6e7570 Add the documentation and new a build option (buildDev). 2024-05-28 08:56:26 +01:00
vorotamoroz
069b8513d1 bump 2024-05-27 12:21:08 +01:00
vorotamoroz
128b1843df Fixed: No longer configurations have been locked in the minimal setup. 2024-05-27 12:20:18 +01:00
17 changed files with 496 additions and 175 deletions

View File

@@ -0,0 +1,34 @@
# How to add translations
## Getting ready
1. Clone this repository recursively.
```sh
git clone --recursive https://github.com/vrtmrz/obsidian-livesync
```
2. Make `ls-debug` folder under your vault's `.obsidian` folder (as like `.../dev/.obsidian/ls-debug`).
## Add translations for already defined terms
1. Install dependencies, and build the plug-in as dev. build.
```sh
cd obsidian-livesync
npm i -D
npm run buildDev
```
2. Copy the `main.js` to `.obsidian/plugins/obsidian-livesync` folder of your vault, and run Obsidian-Self-hosted LiveSync.
3. You will get the `missing-translation-yyyy-mm-dd.jsonl`, please fill in new translations.
4. Build the plug-in again, and confirm that displayed things were expected.
5. Merge them into `rosetta.ts`, and make the PR to `https://github.com/vrtmrz/livesync-commonlib`.
## Make messages to be translated
1. Find the message that you want to be translated.
2. Change the literal to a tagged template literal using `$f`, like below.
```diff
- Logger("Could not determine passphrase to save data.json! You probably make the configuration sure again!", LOG_LEVEL_URGENT);
+ Logger($f`Could not determine passphrase to save data.json! You probably make the configuration sure again!`, LOG_LEVEL_URGENT);
```
3. Make the PR to `https://github.com/vrtmrz/obsidian-livesync`.
4. Follow the steps of "Add translations for already defined terms" to add the translations.

View File

@@ -8,27 +8,31 @@ import sveltePreprocess from "svelte-preprocess";
import fs from "node:fs"; import fs from "node:fs";
// import terser from "terser"; // import terser from "terser";
import { minify } from "terser"; import { minify } from "terser";
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
const banner = `/* const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD AND TERSER THIS IS A GENERATED/BUNDLED FILE BY ESBUILD AND TERSER
if you want to view the source, please visit the github repository of this plugin if you want to view the source, please visit the github repository of this plugin
*/ */
`; `;
const prod = process.argv[2] === "production"; const prod = process.argv[2] === "production";
const keepTest = !prod; const dev = process.argv[2] === "dev";
const keepTest = !prod || dev;
const terserOpt = { const terserOpt = {
sourceMap: (!prod ? { sourceMap: !prod
url: "inline" ? {
} : {}), url: "inline",
}
: {},
format: { format: {
indent_level: 2, indent_level: 2,
beautify: true, beautify: true,
comments: "some", comments: "some",
ecma: 2018, ecma: 2018,
preamble: banner, preamble: banner,
webkit: true webkit: true,
}, },
parse: { parse: {
// parse options // parse options
@@ -53,16 +57,6 @@ const terserOpt = {
ecma: 2018, ecma: 2018,
unused: true, unused: true,
}, },
// mangle: {
// // mangle options
// keep_classnames: true,
// keep_fnames: true,
// properties: {
// // mangle property options
// }
// },
ecma: 2018, // specify one of: 5, 2015, 2016, etc. ecma: 2018, // specify one of: 5, 2015, 2016, etc.
enclose: false, // or specify true, or "args:values" enclose: false, // or specify true, or "args:values"
@@ -72,42 +66,43 @@ const terserOpt = {
module: false, module: false,
// nameCache: null, // or specify a name cache object // nameCache: null, // or specify a name cache object
safari10: false, safari10: false,
toplevel: false toplevel: false,
} };
const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + ""); const manifestJson = JSON.parse(fs.readFileSync("./manifest.json") + "");
const packageJson = JSON.parse(fs.readFileSync("./package.json") + ""); const packageJson = JSON.parse(fs.readFileSync("./package.json") + "");
const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + ""); const updateInfo = JSON.stringify(fs.readFileSync("./updates.md") + "");
/** @type esbuild.Plugin[] */ /** @type esbuild.Plugin[] */
const plugins = [{ const plugins = [
name: 'my-plugin', {
setup(build) { name: "my-plugin",
let count = 0; setup(build) {
build.onEnd(async result => { let count = 0;
if (count++ === 0) { build.onEnd(async (result) => {
console.log('first build:', result); if (count++ === 0) {
console.log("first build:", result);
} else { } else {
console.log('subsequent build:'); console.log("subsequent build:");
}
if (prod) {
console.log("Performing terser");
const src = fs.readFileSync("./main_org.js").toString();
// @ts-ignore
const ret = await minify(src, terserOpt);
if (ret && ret.code) {
fs.writeFileSync("./main.js", ret.code);
} }
console.log("Finished terser"); if (prod) {
} else { console.log("Performing terser");
fs.copyFileSync("./main_org.js", "./main.js"); const src = fs.readFileSync("./main_org.js").toString();
} // @ts-ignore
}); const ret = await minify(src, terserOpt);
if (ret && ret.code) {
fs.writeFileSync("./main.js", ret.code);
}
console.log("Finished terser");
} else {
fs.copyFileSync("./main_org.js", "./main.js");
}
});
},
}, },
}]; ];
const externals = ["obsidian", "electron", "crypto", "@codemirror/autocomplete", "@codemirror/collab", "@codemirror/commands", "@codemirror/language", "@codemirror/lint", "@codemirror/search", "@codemirror/state", "@codemirror/view", "@lezer/common", "@lezer/highlight", "@lezer/lr"];
const context = await esbuild.context({ const context = await esbuild.context({
banner: { banner: {
js: banner, js: banner,
@@ -115,26 +110,12 @@ const context = await esbuild.context({
entryPoints: ["src/main.ts"], entryPoints: ["src/main.ts"],
bundle: true, bundle: true,
define: { define: {
"MANIFEST_VERSION": `"${manifestJson.version}"`, MANIFEST_VERSION: `"${manifestJson.version}"`,
"PACKAGE_VERSION": `"${packageJson.version}"`, PACKAGE_VERSION: `"${packageJson.version}"`,
"UPDATE_INFO": `${updateInfo}`, UPDATE_INFO: `${updateInfo}`,
"global": "window", global: "window",
}, },
external: [ external: externals,
"obsidian",
"electron",
"crypto",
"@codemirror/autocomplete",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/search",
"@codemirror/state",
"@codemirror/view",
"@lezer/common",
"@lezer/highlight",
"@lezer/lr"],
// minifyWhitespace: true, // minifyWhitespace: true,
format: "cjs", format: "cjs",
target: "es2018", target: "es2018",
@@ -151,15 +132,19 @@ const context = await esbuild.context({
dropLabels: prod && !keepTest ? ["TEST", "DEV"] : [], dropLabels: prod && !keepTest ? ["TEST", "DEV"] : [],
// keepNames: true, // keepNames: true,
plugins: [ plugins: [
inlineWorkerPlugin({
external: externals,
treeShaking: true,
}),
sveltePlugin({ sveltePlugin({
preprocess: sveltePreprocess(), preprocess: sveltePreprocess(),
compilerOptions: { css: "injected", preserveComments: false }, compilerOptions: { css: "injected", preserveComments: false },
}), }),
...plugins ...plugins,
], ],
}) });
if (prod) { if (prod || dev) {
await context.rebuild(); await context.rebuild();
process.exit(0); process.exit(0);
} else { } else {

View File

@@ -1,7 +1,7 @@
{ {
"id": "obsidian-livesync", "id": "obsidian-livesync",
"name": "Self-hosted LiveSync", "name": "Self-hosted LiveSync",
"version": "0.23.9", "version": "0.23.13",
"minAppVersion": "0.9.12", "minAppVersion": "0.9.12",
"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.", "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", "author": "vorotamoroz",

277
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.23.9", "version": "0.23.13",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.23.9", "version": "0.23.13",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.556.0", "@aws-sdk/client-s3": "^3.556.0",
@@ -14,6 +14,7 @@
"@smithy/protocol-http": "^3.3.0", "@smithy/protocol-http": "^3.3.0",
"@smithy/querystring-builder": "^2.2.0", "@smithy/querystring-builder": "^2.2.0",
"diff-match-patch": "^1.0.5", "diff-match-patch": "^1.0.5",
"esbuild-plugin-inline-worker": "^0.1.1",
"fflate": "^0.8.2", "fflate": "^0.8.2",
"idb": "^8.0.0", "idb": "^8.0.0",
"minimatch": "^9.0.3", "minimatch": "^9.0.3",
@@ -54,7 +55,7 @@
"pouchdb-merge": "^8.0.1", "pouchdb-merge": "^8.0.1",
"pouchdb-replication": "^8.0.1", "pouchdb-replication": "^8.0.1",
"pouchdb-utils": "^8.0.1", "pouchdb-utils": "^8.0.1",
"svelte": "^4.2.12", "svelte": "^4.2.16",
"svelte-preprocess": "^5.1.3", "svelte-preprocess": "^5.1.3",
"terser": "^5.29.2", "terser": "^5.29.2",
"transform-pouch": "^2.0.0", "transform-pouch": "^2.0.0",
@@ -909,7 +910,6 @@
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"aix" "aix"
@@ -925,7 +925,6 @@
"cpu": [ "cpu": [
"arm" "arm"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"android" "android"
@@ -941,7 +940,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"android" "android"
@@ -957,7 +955,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"android" "android"
@@ -973,7 +970,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"darwin" "darwin"
@@ -989,7 +985,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"darwin" "darwin"
@@ -1005,7 +1000,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"freebsd" "freebsd"
@@ -1021,7 +1015,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"freebsd" "freebsd"
@@ -1037,7 +1030,6 @@
"cpu": [ "cpu": [
"arm" "arm"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1053,7 +1045,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1069,7 +1060,6 @@
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1085,7 +1075,6 @@
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1101,7 +1090,6 @@
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1117,7 +1105,6 @@
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1133,7 +1120,6 @@
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1149,7 +1135,6 @@
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1165,7 +1150,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"linux" "linux"
@@ -1181,7 +1165,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"netbsd" "netbsd"
@@ -1197,7 +1180,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"openbsd" "openbsd"
@@ -1213,7 +1195,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"sunos" "sunos"
@@ -1229,7 +1210,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"win32" "win32"
@@ -1245,7 +1225,6 @@
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"win32" "win32"
@@ -1261,7 +1240,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"optional": true, "optional": true,
"os": [ "os": [
"win32" "win32"
@@ -3013,6 +2991,11 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true "dev": true
}, },
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -3288,7 +3271,6 @@
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
"integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"bin": { "bin": {
"esbuild": "bin/esbuild" "esbuild": "bin/esbuild"
@@ -3322,6 +3304,15 @@
"@esbuild/win32-x64": "0.20.2" "@esbuild/win32-x64": "0.20.2"
} }
}, },
"node_modules/esbuild-plugin-inline-worker": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/esbuild-plugin-inline-worker/-/esbuild-plugin-inline-worker-0.1.1.tgz",
"integrity": "sha512-VmFqsQKxUlbM51C1y5bRiMeyc1x2yTdMXhKB6S//++g9aCBg8TfGsbKxl5ZDkCGquqLY+RmEk93TBNd0i35dPA==",
"dependencies": {
"esbuild": "latest",
"find-cache-dir": "^3.3.1"
}
},
"node_modules/esbuild-svelte": { "node_modules/esbuild-svelte": {
"version": "0.8.0", "version": "0.8.0",
"resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.8.0.tgz", "resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.8.0.tgz",
@@ -3815,6 +3806,22 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"dependencies": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
"node_modules/find-up": { "node_modules/find-up": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -4591,6 +4598,28 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dependencies": {
"semver": "^6.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/mdn-data": { "node_modules/mdn-data": {
"version": "2.0.30", "version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@@ -4886,6 +4915,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/parent-module": { "node_modules/parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -4902,7 +4939,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@@ -4969,6 +5005,65 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dependencies": {
"find-up": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pkg-dir/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pkg-dir/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pkg-dir/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/pkg-dir/node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/possible-typed-array-names": { "node_modules/possible-typed-array-names": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -5780,9 +5875,9 @@
} }
}, },
"node_modules/svelte": { "node_modules/svelte": {
"version": "4.2.12", "version": "4.2.17",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.17.tgz",
"integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", "integrity": "sha512-N7m1YnoXtRf5wya5Gyx3TWuTddI4nAyayyIWFojiWV5IayDYNV5i2mRp/7qNGol4DtxEYxljmrbgp1HM6hUbmQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@ampproject/remapping": "^2.2.1", "@ampproject/remapping": "^2.2.1",
@@ -7015,161 +7110,138 @@
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
"integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/android-arm": { "@esbuild/android-arm": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
"integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/android-arm64": { "@esbuild/android-arm64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
"integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/android-x64": { "@esbuild/android-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
"integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/darwin-arm64": { "@esbuild/darwin-arm64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
"integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/darwin-x64": { "@esbuild/darwin-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
"integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/freebsd-arm64": { "@esbuild/freebsd-arm64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
"integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/freebsd-x64": { "@esbuild/freebsd-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
"integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-arm": { "@esbuild/linux-arm": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
"integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-arm64": { "@esbuild/linux-arm64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
"integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-ia32": { "@esbuild/linux-ia32": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
"integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-loong64": { "@esbuild/linux-loong64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
"integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-mips64el": { "@esbuild/linux-mips64el": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
"integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-ppc64": { "@esbuild/linux-ppc64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
"integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-riscv64": { "@esbuild/linux-riscv64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
"integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-s390x": { "@esbuild/linux-s390x": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
"integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/linux-x64": { "@esbuild/linux-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
"integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/netbsd-x64": { "@esbuild/netbsd-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
"integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/openbsd-x64": { "@esbuild/openbsd-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
"integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/sunos-x64": { "@esbuild/sunos-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
"integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/win32-arm64": { "@esbuild/win32-arm64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
"integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/win32-ia32": { "@esbuild/win32-ia32": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
"integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"dev": true,
"optional": true "optional": true
}, },
"@esbuild/win32-x64": { "@esbuild/win32-x64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
"integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"dev": true,
"optional": true "optional": true
}, },
"@eslint-community/eslint-utils": { "@eslint-community/eslint-utils": {
@@ -8542,6 +8614,11 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true "dev": true
}, },
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
},
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -8758,7 +8835,6 @@
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
"integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"requires": { "requires": {
"@esbuild/aix-ppc64": "0.20.2", "@esbuild/aix-ppc64": "0.20.2",
"@esbuild/android-arm": "0.20.2", "@esbuild/android-arm": "0.20.2",
@@ -8785,6 +8861,15 @@
"@esbuild/win32-x64": "0.20.2" "@esbuild/win32-x64": "0.20.2"
} }
}, },
"esbuild-plugin-inline-worker": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/esbuild-plugin-inline-worker/-/esbuild-plugin-inline-worker-0.1.1.tgz",
"integrity": "sha512-VmFqsQKxUlbM51C1y5bRiMeyc1x2yTdMXhKB6S//++g9aCBg8TfGsbKxl5ZDkCGquqLY+RmEk93TBNd0i35dPA==",
"requires": {
"esbuild": "latest",
"find-cache-dir": "^3.3.1"
}
},
"esbuild-svelte": { "esbuild-svelte": {
"version": "0.8.0", "version": "0.8.0",
"resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.8.0.tgz", "resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.8.0.tgz",
@@ -9168,6 +9253,16 @@
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
} }
}, },
"find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"requires": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
}
},
"find-up": { "find-up": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -9721,6 +9816,21 @@
"@jridgewell/sourcemap-codec": "^1.4.15" "@jridgewell/sourcemap-codec": "^1.4.15"
} }
}, },
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"requires": {
"semver": "^6.0.0"
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
"mdn-data": { "mdn-data": {
"version": "2.0.30", "version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@@ -9926,6 +10036,11 @@
"p-limit": "^3.0.2" "p-limit": "^3.0.2"
} }
}, },
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"parent-module": { "parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -9938,8 +10053,7 @@
"path-exists": { "path-exists": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
"dev": true
}, },
"path-is-absolute": { "path-is-absolute": {
"version": "1.0.1", "version": "1.0.1",
@@ -9988,6 +10102,49 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true "dev": true
}, },
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"requires": {
"find-up": "^4.0.0"
},
"dependencies": {
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"requires": {
"p-locate": "^4.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"requires": {
"p-limit": "^2.2.0"
}
}
}
},
"possible-typed-array-names": { "possible-typed-array-names": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@@ -10610,9 +10767,9 @@
"dev": true "dev": true
}, },
"svelte": { "svelte": {
"version": "4.2.12", "version": "4.2.17",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.17.tgz",
"integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", "integrity": "sha512-N7m1YnoXtRf5wya5Gyx3TWuTddI4nAyayyIWFojiWV5IayDYNV5i2mRp/7qNGol4DtxEYxljmrbgp1HM6hUbmQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@ampproject/remapping": "^2.2.1", "@ampproject/remapping": "^2.2.1",

View File

@@ -1,12 +1,13 @@
{ {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.23.9", "version": "0.23.13",
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.", "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", "main": "main.js",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "node esbuild.config.mjs", "dev": "node esbuild.config.mjs",
"build": "node esbuild.config.mjs production", "build": "node esbuild.config.mjs production",
"buildDev": "node esbuild.config.mjs dev",
"lint": "eslint src" "lint": "eslint src"
}, },
"keywords": [], "keywords": [],
@@ -46,7 +47,7 @@
"pouchdb-merge": "^8.0.1", "pouchdb-merge": "^8.0.1",
"pouchdb-replication": "^8.0.1", "pouchdb-replication": "^8.0.1",
"pouchdb-utils": "^8.0.1", "pouchdb-utils": "^8.0.1",
"svelte": "^4.2.12", "svelte": "^4.2.16",
"svelte-preprocess": "^5.1.3", "svelte-preprocess": "^5.1.3",
"terser": "^5.29.2", "terser": "^5.29.2",
"transform-pouch": "^2.0.0", "transform-pouch": "^2.0.0",
@@ -59,6 +60,7 @@
"@smithy/protocol-http": "^3.3.0", "@smithy/protocol-http": "^3.3.0",
"@smithy/querystring-builder": "^2.2.0", "@smithy/querystring-builder": "^2.2.0",
"diff-match-patch": "^1.0.5", "diff-match-patch": "^1.0.5",
"esbuild-plugin-inline-worker": "^0.1.1",
"fflate": "^0.8.2", "fflate": "^0.8.2",
"idb": "^8.0.0", "idb": "^8.0.0",
"minimatch": "^9.0.3", "minimatch": "^9.0.3",

View File

@@ -6,7 +6,7 @@ import { LOG_LEVEL_VERBOSE, type AnyEntry, type DocumentID, type EntryHasPath, t
import { CHeader, ICHeader, ICHeaderLength, ICXHeader, PSCHeader } from "./types.ts"; import { CHeader, ICHeader, ICHeaderLength, ICXHeader, PSCHeader } from "./types.ts";
import { InputStringDialog, PopoverSelectString } from "./dialogs.ts"; import { InputStringDialog, PopoverSelectString } from "./dialogs.ts";
import type ObsidianLiveSyncPlugin from "../main.ts"; import type ObsidianLiveSyncPlugin from "../main.ts";
import { writeString } from "../lib/src/string_and_binary/strbin.ts"; import { writeString } from "../lib/src/string_and_binary/convert.ts";
import { fireAndForget } from "../lib/src/common/utils.ts"; import { fireAndForget } from "../lib/src/common/utils.ts";
import { sameChangePairs } from "./stores.ts"; import { sameChangePairs } from "./stores.ts";

View File

@@ -4,9 +4,10 @@ import { Notice, type PluginManifest, parseYaml, normalizePath, type ListedFiles
import type { EntryDoc, LoadedEntry, InternalFileEntry, FilePathWithPrefix, FilePath, DocumentID, AnyEntry, SavingEntry } from "../lib/src/common/types.ts"; import type { EntryDoc, LoadedEntry, InternalFileEntry, FilePathWithPrefix, FilePath, DocumentID, AnyEntry, SavingEntry } from "../lib/src/common/types.ts";
import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, MODE_SELECTIVE } from "../lib/src/common/types.ts"; import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, MODE_SELECTIVE } from "../lib/src/common/types.ts";
import { ICXHeader, PERIODIC_PLUGIN_SWEEP, } from "../common/types.ts"; import { ICXHeader, PERIODIC_PLUGIN_SWEEP, } from "../common/types.ts";
import { createSavingEntryFromLoadedEntry, createTextBlob, delay, fireAndForget, getDocDataAsArray, isDocContentSame, throttle } from "../lib/src/common/utils.ts"; import { createSavingEntryFromLoadedEntry, createTextBlob, delay, fireAndForget, getDocDataAsArray, isDocContentSame } from "../lib/src/common/utils.ts";
import { Logger } from "../lib/src/common/logger.ts"; import { Logger } from "../lib/src/common/logger.ts";
import { readString, decodeBinary, arrayBufferToBase64, digestHash } from "../lib/src/string_and_binary/strbin.ts"; import { digestHash } from "../lib/src/string_and_binary/hash.ts";
import { arrayBufferToBase64, decodeBinary, readString } from 'src/lib/src/string_and_binary/convert.ts';
import { serialized, shareRunningResult } from "../lib/src/concurrency/lock.ts"; import { serialized, shareRunningResult } from "../lib/src/concurrency/lock.ts";
import { LiveSyncCommands } from "./LiveSyncCommands.ts"; import { LiveSyncCommands } from "./LiveSyncCommands.ts";
import { stripAllPrefixes } from "../lib/src/string_and_binary/path.ts"; import { stripAllPrefixes } from "../lib/src/string_and_binary/path.ts";
@@ -19,7 +20,6 @@ import type ObsidianLiveSyncPlugin from '../main.ts';
const d = "\u200b"; const d = "\u200b";
const d2 = "\n"; const d2 = "\n";
const delimiters = /(?<=[\n|\u200b])/g;
function serialize(data: PluginDataEx): string { function serialize(data: PluginDataEx): string {
@@ -42,8 +42,45 @@ function serialize(data: PluginDataEx): string {
return ret; return ret;
} }
function splitWithDelimiters(sources: string[]): string[] {
const result: string[] = [];
for (const str of sources) {
let startIndex = 0;
const maxLen = str.length;
let i = -1;
let i1;
let i2;
do {
i1 = str.indexOf(d, startIndex);
i2 = str.indexOf(d2, startIndex);
if (i1 == -1 && i2 == -1) {
break;
}
if (i1 == -1) {
i = i2;
} else if (i2 == -1) {
i = i1;
} else {
i = i1 < i2 ? i1 : i2;
}
result.push(str.slice(startIndex, i + 1));
startIndex = i + 1;
} while (i < maxLen);
if (startIndex < maxLen) {
result.push(str.slice(startIndex));
}
}
// To keep compatibilities
if (sources[sources.length - 1] == "") {
result.push("");
}
return result;
}
function getTokenizer(source: string[]) { function getTokenizer(source: string[]) {
const sources = source.flatMap(e => e.split(delimiters)) const sources = splitWithDelimiters(source);
sources[0] = sources[0].substring(1); sources[0] = sources[0].substring(1);
let pos = 0; let pos = 0;
let lineRunOut = false; let lineRunOut = false;
@@ -318,8 +355,7 @@ export class ConfigSync extends LiveSyncCommands {
} }
return false; return false;
} }
createMissingConfigurationEntry = throttle(() => this._createMissingConfigurationEntry(), 1000); async createMissingConfigurationEntry() {
_createMissingConfigurationEntry() {
let saveRequired = false; let saveRequired = false;
for (const v of this.pluginList) { for (const v of this.pluginList) {
const key = `${v.category}/${v.name}`; const key = `${v.category}/${v.name}`;
@@ -337,7 +373,7 @@ export class ConfigSync extends LiveSyncCommands {
} }
} }
if (saveRequired) { if (saveRequired) {
this.plugin.saveSettingData(); await this.plugin.saveSettingData();
} }
} }
@@ -365,7 +401,11 @@ export class ConfigSync extends LiveSyncCommands {
} }
return []; return [];
}, { suspended: false, batchSize: 1, concurrentLimit: 10, delay: 100, yieldThreshold: 10, maintainDelay: false, totalRemainingReactiveSource: pluginScanningCount }).startPipeline().root.onUpdateProgress(() => { }, { suspended: false, batchSize: 1, concurrentLimit: 10, delay: 100, yieldThreshold: 10, maintainDelay: false, totalRemainingReactiveSource: pluginScanningCount }).startPipeline().root.onUpdateProgress(() => {
this.createMissingConfigurationEntry(); scheduleTask("checkMissingConfigurations", 250, async () => {
if (this.pluginScanProcessor.isIdle()) {
await this.createMissingConfigurationEntry();
}
});
}); });
@@ -654,7 +694,7 @@ export class ConfigSync extends LiveSyncCommands {
for (const target of fileTargets) { for (const target of fileTargets) {
const data = await this.makeEntryFromFile(target); const data = await this.makeEntryFromFile(target);
if (data == false) { if (data == false) {
// Logger(`Config: skipped: ${target} `, LOG_LEVEL_VERBOSE); Logger(`Config: skipped (Possibly is not exist): ${target} `, LOG_LEVEL_VERBOSE);
continue; continue;
} }
if (data.version) { if (data.version) {
@@ -703,13 +743,15 @@ export class ConfigSync extends LiveSyncCommands {
const oldC = await this.localDatabase.getDBEntryFromMeta(old, {}, false, false); const oldC = await this.localDatabase.getDBEntryFromMeta(old, {}, false, false);
if (oldC) { if (oldC) {
const d = await deserialize(getDocDataAsArray(oldC.data), {}) as PluginDataEx; const d = await deserialize(getDocDataAsArray(oldC.data), {}) as PluginDataEx;
const diffs = (d.files.map(previous => ({ prev: previous, curr: dt.files.find(e => e.filename == previous.filename) })).map(async e => { if (d.files.length == dt.files.length) {
try { return await isDocContentSame(e.curr?.data ?? [], e.prev.data) } catch (_) { return false } const diffs = (d.files.map(previous => ({ prev: previous, curr: dt.files.find(e => e.filename == previous.filename) })).map(async e => {
})) try { return await isDocContentSame(e.curr?.data ?? [], e.prev.data) } catch (_) { return false }
const isSame = (await Promise.all(diffs)).every(e => e == true); }))
if (isSame) { const isSame = (await Promise.all(diffs)).every(e => e == true);
Logger(`STORAGE --> DB:${prefixedFileName}: (config) Skipped (Same content)`, LOG_LEVEL_VERBOSE); if (isSame) {
return true; Logger(`STORAGE --> DB:${prefixedFileName}: (config) Skipped (Same content)`, LOG_LEVEL_VERBOSE);
return true;
}
} }
} }
saveData = saveData =
@@ -757,9 +799,11 @@ export class ConfigSync extends LiveSyncCommands {
return true; return true;
} }
this.recentProcessedInternalFiles = [key, ...this.recentProcessedInternalFiles].slice(0, 100); this.recentProcessedInternalFiles = [key, ...this.recentProcessedInternalFiles].slice(0, 100);
// To prevent saving half-collected file sets.
this.storeCustomizationFiles(path).then(() => {/* Fire and forget */ }); const keySchedule = this.filenameToUnifiedKey(path);
scheduleTask(keySchedule, 100, async () => {
await this.storeCustomizationFiles(path);
})
} }

Submodule src/lib updated: 302a2e7c0b...eb39d533e4

View File

@@ -15,7 +15,7 @@ import { encrypt, tryDecrypt } from "./lib/src/encryption/e2ee_v2.ts";
import { balanceChunkPurgedDBs, enableCompression, enableEncryption, isCloudantURI, isErrorOfMissingDoc, isValidRemoteCouchDBURI, purgeUnreferencedChunks } from "./lib/src/pouchdb/utils_couchdb.ts"; import { balanceChunkPurgedDBs, enableCompression, enableEncryption, isCloudantURI, isErrorOfMissingDoc, isValidRemoteCouchDBURI, purgeUnreferencedChunks } from "./lib/src/pouchdb/utils_couchdb.ts";
import { logStore, type LogEntry, collectingChunks, pluginScanningCount, hiddenFilesProcessingCount, hiddenFilesEventCount, logMessages } from "./lib/src/mock_and_interop/stores.ts"; import { logStore, type LogEntry, collectingChunks, pluginScanningCount, hiddenFilesProcessingCount, hiddenFilesEventCount, logMessages } from "./lib/src/mock_and_interop/stores.ts";
import { setNoticeClass } from "./lib/src/mock_and_interop/wrapper.ts"; import { setNoticeClass } from "./lib/src/mock_and_interop/wrapper.ts";
import { versionNumberString2Number, writeString, decodeBinary, readString } from "./lib/src/string_and_binary/strbin.ts"; import { versionNumberString2Number, writeString, decodeBinary, readString } from "./lib/src/string_and_binary/convert.ts";
import { addPrefix, isAcceptedAll, isPlainText, shouldBeIgnored, stripAllPrefixes } from "./lib/src/string_and_binary/path.ts"; import { addPrefix, isAcceptedAll, isPlainText, shouldBeIgnored, stripAllPrefixes } from "./lib/src/string_and_binary/path.ts";
import { isLockAcquired, serialized, shareRunningResult, skipIfDuplicated } from "./lib/src/concurrency/lock.ts"; import { isLockAcquired, serialized, shareRunningResult, skipIfDuplicated } from "./lib/src/concurrency/lock.ts";
import { StorageEventManager, StorageEventManagerObsidian } from "./storages/StorageEventManager.ts"; import { StorageEventManager, StorageEventManagerObsidian } from "./storages/StorageEventManager.ts";
@@ -41,6 +41,8 @@ import type { CheckPointInfo } from "./lib/src/replication/journal/JournalSyncTy
import { ObsHttpHandler } from "./common/ObsHttpHandler.js"; import { ObsHttpHandler } from "./common/ObsHttpHandler.js";
import { TestPaneView, VIEW_TYPE_TEST } from "./tests/TestPaneView.js" import { TestPaneView, VIEW_TYPE_TEST } from "./tests/TestPaneView.js"
import { $f, __onMissingTranslation, setLang } from "./lib/src/common/i18n.ts"; import { $f, __onMissingTranslation, setLang } from "./lib/src/common/i18n.ts";
import { enableTestFunction } from "./tests/testUtils.ts";
import { terminateWorker } from "./lib/src/worker/splitWorker.ts";
setNoticeClass(Notice); setNoticeClass(Notice);
@@ -855,6 +857,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
); );
// eslint-disable-next-line no-unused-labels // eslint-disable-next-line no-unused-labels
TEST: { TEST: {
enableTestFunction(this);
this.registerView( this.registerView(
VIEW_TYPE_TEST, VIEW_TYPE_TEST,
(leaf) => new TestPaneView(leaf, this) (leaf) => new TestPaneView(leaf, this)
@@ -870,14 +873,13 @@ Note: We can always able to read V1 format. It will be progressively converted.
this.showView(VIEW_TYPE_TEST); this.showView(VIEW_TYPE_TEST);
} }
}); });
} }
} }
async onload() { async onload() {
logStore.pipeTo(new QueueProcessor(logs => logs.forEach(e => this.addLog(e.message, e.level, e.key)), { suspended: false, batchSize: 20, concurrentLimit: 1, delay: 0 })).startPipeline(); logStore.pipeTo(new QueueProcessor(logs => logs.forEach(e => this.addLog(e.message, e.level, e.key)), { suspended: false, batchSize: 20, concurrentLimit: 1, delay: 0 })).startPipeline();
Logger("loading plugin"); Logger("loading plugin");
__onMissingTranslation(() => { });
// eslint-disable-next-line no-unused-labels // eslint-disable-next-line no-unused-labels
DEV: { DEV: {
__onMissingTranslation((key) => { __onMissingTranslation((key) => {
@@ -981,6 +983,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
} }
onunload() { onunload() {
terminateWorker();
cancelAllPeriodicTask(); cancelAllPeriodicTask();
cancelAllTasks(); cancelAllTasks();
stopAllRunningProcessors(); stopAllRunningProcessors();
@@ -1137,12 +1140,14 @@ Note: We can always able to read V1 format. It will be progressively converted.
this.settingTab.requestReload() this.settingTab.requestReload()
} }
async saveSettingData() { saveDeviceAndVaultName() {
const lsKey = "obsidian-live-sync-vaultanddevicename-" + this.getVaultName(); const lsKey = "obsidian-live-sync-vaultanddevicename-" + this.getVaultName();
localStorage.setItem(lsKey, this.deviceAndVaultName || ""); localStorage.setItem(lsKey, this.deviceAndVaultName || "");
}
async saveSettingData() {
this.saveDeviceAndVaultName();
const settings = { ...this.settings }; const settings = { ...this.settings };
settings.deviceAndVaultName = "";
if (this.usedPassphrase == "" && !await this.getPassphrase(settings)) { if (this.usedPassphrase == "" && !await this.getPassphrase(settings)) {
Logger("Could not determine passphrase for saving data.json! Our data.json have insecure items!", LOG_LEVEL_NOTICE); Logger("Could not determine passphrase for saving data.json! Our data.json have insecure items!", LOG_LEVEL_NOTICE);
} else { } else {
@@ -3060,28 +3065,28 @@ Or if you are sure know what had been happened, we can unlock the database from
const ret = await this.localDatabase.putDBEntry(d); const ret = await this.localDatabase.putDBEntry(d);
if (ret !== false) { if (ret !== false) {
Logger(msg + fullPath); Logger(msg + fullPath);
if (this.settings.syncOnSave && !this.suspended) { this.scheduleReplicateIfSyncOnSave();
scheduleTask("perform-replicate-after-save", 250, () => this.replicate());
}
} }
return ret != false; return ret != false;
} }
scheduleReplicateIfSyncOnSave() {
if (this.settings.syncOnSave && !this.suspended) {
scheduleTask("perform-replicate-after-save", 250, () => this.replicate());
}
}
async deleteFromDB(file: TFile) { async deleteFromDB(file: TFile) {
if (!await this.isTargetFile(file)) return; if (!await this.isTargetFile(file)) return;
const fullPath = getPathFromTFile(file); const fullPath = getPathFromTFile(file);
Logger(`deleteDB By path:${fullPath}`); Logger(`deleteDB By path:${fullPath}`);
await this.deleteFromDBbyPath(fullPath); await this.deleteFromDBbyPath(fullPath);
if (this.settings.syncOnSave && !this.suspended) { this.scheduleReplicateIfSyncOnSave();
await this.replicate();
}
} }
async deleteFromDBbyPath(fullPath: FilePath) { async deleteFromDBbyPath(fullPath: FilePath) {
await this.localDatabase.deleteDBEntry(fullPath); await this.localDatabase.deleteDBEntry(fullPath);
if (this.settings.syncOnSave && !this.suspended) { this.scheduleReplicateIfSyncOnSave();
await this.replicate();
}
} }
async resetLocalDatabase() { async resetLocalDatabase() {

45
src/tests/testUtils.ts Normal file
View File

@@ -0,0 +1,45 @@
import { fireAndForget } from "src/lib/src/common/utils";
import { serialized } from "src/lib/src/concurrency/lock";
import type ObsidianLiveSyncPlugin from "src/main";
let plugin: ObsidianLiveSyncPlugin;
export function enableTestFunction(plugin_: ObsidianLiveSyncPlugin) {
plugin = plugin_;
}
export function addDebugFileLog(message: any, stackLog = false) {
fireAndForget(serialized("debug-log", async () => {
const now = new Date();
const filename = `debug-log`
const time = now.toISOString().split("T")[0];
const outFile = `${filename}${time}.jsonl`;
// const messageContent = typeof message == "string" ? message : message instanceof Error ? `${message.name}:${message.message}` : JSON.stringify(message, null, 2);
const timestamp = now.toLocaleString();
const timestampEpoch = now;
let out = { "timestamp": timestamp, epoch: timestampEpoch, } as Record<string, any>;
if (message instanceof Error) {
// debugger;
// console.dir(message.stack);
out = { ...out, message };
} else if (stackLog) {
if (stackLog) {
const stackE = new Error();
const stack = stackE.stack;
out = { ...out, stack }
}
}
if (typeof message == "object") {
out = { ...out, ...message, }
} else {
out = {
result: message
}
}
// const out = "--" + timestamp + "--\n" + messageContent + " " + (stack || "");
// const out
try {
await plugin.vaultAccess.adapterAppend(plugin.app.vault.configDir + "/ls-debug/" + outFile, JSON.stringify(out) + "\n")
} catch (ex) {
//NO OP
}
}));
}

View File

@@ -1,7 +1,7 @@
import { App, Modal } from "../deps.ts"; import { App, Modal } from "../deps.ts";
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch"; import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch";
import { CANCELLED, LEAVE_TO_SUBSEQUENT, RESULT_TIMED_OUT, type diff_result } from "../lib/src/common/types.ts"; import { CANCELLED, LEAVE_TO_SUBSEQUENT, RESULT_TIMED_OUT, type diff_result } from "../lib/src/common/types.ts";
import { escapeStringToHTML } from "../lib/src/string_and_binary/strbin.ts"; import { escapeStringToHTML } from "../lib/src/string_and_binary/convert.ts";
import { delay, sendValue, waitForValue } from "../lib/src/common/utils.ts"; import { delay, sendValue, waitForValue } from "../lib/src/common/utils.ts";
export type MergeDialogResult = typeof LEAVE_TO_SUBSEQUENT | typeof CANCELLED | string; export type MergeDialogResult = typeof LEAVE_TO_SUBSEQUENT | typeof CANCELLED | string;

View File

@@ -1,6 +1,6 @@
import { TFile, Modal, App, DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "../deps.ts"; import { TFile, Modal, App, DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from "../deps.ts";
import { getPathFromTFile, isValidPath } from "../common/utils.ts"; import { getPathFromTFile, isValidPath } from "../common/utils.ts";
import { decodeBinary, escapeStringToHTML, readString } from "../lib/src/string_and_binary/strbin.ts"; import { decodeBinary, escapeStringToHTML, readString } from "../lib/src/string_and_binary/convert.ts";
import ObsidianLiveSyncPlugin from "../main.ts"; import ObsidianLiveSyncPlugin from "../main.ts";
import { type DocumentID, type FilePathWithPrefix, type LoadedEntry, LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "../lib/src/common/types.ts"; import { type DocumentID, type FilePathWithPrefix, type LoadedEntry, LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "../lib/src/common/types.ts";
import { Logger } from "../lib/src/common/logger.ts"; import { Logger } from "../lib/src/common/logger.ts";

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { type Diff, DIFF_DELETE, DIFF_INSERT, diff_match_patch } from "../deps"; import { type Diff, DIFF_DELETE, DIFF_INSERT, diff_match_patch } from "../deps";
import type { FilePath, LoadedEntry } from "../lib/src/common/types"; import type { FilePath, LoadedEntry } from "../lib/src/common/types";
import { decodeBinary, readString } from "../lib/src/string_and_binary/strbin"; import { decodeBinary, readString } from "../lib/src/string_and_binary/convert";
import { getDocData } from "../lib/src/common/utils"; import { getDocData } from "../lib/src/common/utils";
import { mergeObject } from "../common/utils"; import { mergeObject } from "../common/utils";

View File

@@ -22,7 +22,7 @@ import {
type ConfigurationItem type ConfigurationItem
} from "../lib/src/common/types.ts"; } from "../lib/src/common/types.ts";
import { createBlob, delay, isDocContentSame, isObjectDifferent, readAsBlob, unique } from "../lib/src/common/utils.ts"; import { createBlob, delay, isDocContentSame, isObjectDifferent, readAsBlob, unique } from "../lib/src/common/utils.ts";
import { versionNumberString2Number } from "../lib/src/string_and_binary/strbin.ts"; import { versionNumberString2Number } from "../lib/src/string_and_binary/convert.ts";
import { Logger } from "../lib/src/common/logger.ts"; import { Logger } from "../lib/src/common/logger.ts";
import { checkSyncInfo, isCloudantURI } from "../lib/src/pouchdb/utils_couchdb.ts"; import { checkSyncInfo, isCloudantURI } from "../lib/src/pouchdb/utils_couchdb.ts";
import { testCrypt } from "../lib/src/encryption/e2ee_v2.ts"; import { testCrypt } from "../lib/src/encryption/e2ee_v2.ts";
@@ -439,6 +439,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
} }
if (key == "deviceAndVaultName") { if (key == "deviceAndVaultName") {
this.plugin.deviceAndVaultName = this.editingSettings?.[key]; this.plugin.deviceAndVaultName = this.editingSettings?.[key];
this.plugin.saveDeviceAndVaultName();
return await Promise.resolve(); return await Promise.resolve();
} }
} }
@@ -519,12 +520,12 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
/** /**
* Reread all settings and request invalidate * Reread all settings and request invalidate
*/ */
reloadAllSettings() { reloadAllSettings(skipUpdate: boolean = false) {
const localSetting = this.reloadAllLocalSettings(); const localSetting = this.reloadAllLocalSettings();
this._editingSettings = { ...this.plugin.settings, ...localSetting }; this._editingSettings = { ...this.plugin.settings, ...localSetting };
this._editingSettings = { ...this.editingSettings, ...this.computeAllLocalSettings() }; this._editingSettings = { ...this.editingSettings, ...this.computeAllLocalSettings() };
this.initialSettings = { ...this.editingSettings, }; this.initialSettings = { ...this.editingSettings, };
this.requestUpdate(); if (!skipUpdate) this.requestUpdate();
} }
/** /**
@@ -667,9 +668,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
this.requestUpdate(); this.requestUpdate();
} }
} else { } else {
Logger(`reread: all! hidden`, LOG_LEVEL_VERBOSE) this.reloadAllSettings(true);
this.reloadAllSettings();
this.display();
} }
} }
@@ -769,7 +768,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
addScreenElement("100", containerInformationEl); addScreenElement("100", containerInformationEl);
const isAnySyncEnabled = (): boolean => { const isAnySyncEnabled = (): boolean => {
if (this.isConfiguredAs("isConfigured", false)) return true; if (this.isConfiguredAs("isConfigured", false)) return false;
if (this.isConfiguredAs("liveSync", true)) return true; if (this.isConfiguredAs("liveSync", true)) return true;
if (this.isConfiguredAs("periodicReplication", true)) return true; if (this.isConfiguredAs("periodicReplication", true)) return true;
if (this.isConfiguredAs("syncOnFileOpen", true)) return true; if (this.isConfiguredAs("syncOnFileOpen", true)) return true;
@@ -1749,6 +1748,10 @@ However, your report is needed to stabilise this. I appreciate you for your grea
.setClass("wizardHidden") .setClass("wizardHidden")
.autoWireToggle("readChunksOnline", { onUpdate: onlyOnCouchDB }) .autoWireToggle("readChunksOnline", { onUpdate: onlyOnCouchDB })
new Setting(containerSyncSettingEl)
.setClass("wizardHidden")
.autoWireToggle("enableChunkSplitterV2")
this.createEl(containerSyncSettingEl, "h4", { this.createEl(containerSyncSettingEl, "h4", {
text: sanitizeHTMLToDom(`Targets`), text: sanitizeHTMLToDom(`Targets`),
}).addClass("wizardHidden"); }).addClass("wizardHidden");
@@ -2185,6 +2188,14 @@ ${stringifyYaml(pluginConfig)}`;
new Setting(containerHatchEl) new Setting(containerHatchEl)
.autoWireToggle("disableCheckingConfigMismatch") .autoWireToggle("disableCheckingConfigMismatch")
new Setting(containerHatchEl)
.autoWireToggle("disableWorkerForGeneratingChunks")
new Setting(containerHatchEl)
.autoWireToggle("processSmallFilesInUIThread", {
onUpdate: visibleOnly(() => this.isConfiguredAs("disableWorkerForGeneratingChunks", false))
})
addScreenElement("50", containerHatchEl); addScreenElement("50", containerHatchEl);

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { PluginDataExDisplay } from "../../features/CmdConfigSync"; import type { PluginDataExDisplay } from "../../features/CmdConfigSync";
import { Logger } from "../../lib/src/common/logger"; import { Logger } from "../../lib/src/common/logger";
import { versionNumberString2Number } from "../../lib/src/string_and_binary/strbin"; import { versionNumberString2Number } from "../../lib/src/string_and_binary/convert";
import { type FilePath, LOG_LEVEL_NOTICE } from "../../lib/src/common/types"; import { type FilePath, LOG_LEVEL_NOTICE } from "../../lib/src/common/types";
import { getDocData } from "../../lib/src/common/utils"; import { getDocData } from "../../lib/src/common/utils";
import type ObsidianLiveSyncPlugin from "../../main"; import type ObsidianLiveSyncPlugin from "../../main";

View File

@@ -300,6 +300,18 @@ export const SettingInformation: Partial<Record<keyof AllSettings, Configuration
"displayLanguage": { "displayLanguage": {
"name": "Display Language", "name": "Display Language",
"desc": "Not all messages have been translated. And, please revert to \"Default\" when reporting errors." "desc": "Not all messages have been translated. And, please revert to \"Default\" when reporting errors."
},
enableChunkSplitterV2: {
name: "Use splitting-limit-capped chunk splitter",
desc: "If enabled, chunks will be split into no more than 100 items. However, dedupe is slightly weaker."
},
disableWorkerForGeneratingChunks: {
name: "Do not split chunks in the background",
desc: "If disabled(toggled), chunks will be split on the UI thread (Previous behaviour)."
},
processSmallFilesInUIThread: {
name: "Process small files in the foreground",
desc: "If enabled, the file under 1kb will be processed in the UI thread."
} }
} }
function translateInfo(infoSrc: ConfigurationItem | undefined | false) { function translateInfo(infoSrc: ConfigurationItem | undefined | false) {

View File

@@ -18,6 +18,32 @@ I have a lot of respect for that plugin, even though it is sometimes treated as
Hooray for open source, and generous licences, and the sharing of knowledge by experts. Hooray for open source, and generous licences, and the sharing of knowledge by experts.
#### Version history #### Version history
- 0.23.13:
- Fixed:
- No longer files have been trimmed even delimiters have been continuous.
- Fixed the toggle title to `Do not split chunks in the background` from `Do not split chunks in the foreground`.
- Non-configured item mismatches are no longer detected.
- 0.23.12:
- Improved:
- Now notes will be split into chunks in the background thread to improve smoothness.
- Default enabled, to disable, toggle `Do not split chunks in the foreground` on `Hatch` -> `Compatibility`.
- If you want to process very small notes in the foreground, please enable `Process small files in the foreground` on `Hatch` -> `Compatibility`.
- We can use a `splitting-limit-capped chunk splitter`; which performs more simple and make less amount of chunks.
- Default disabled, to enable, toggle `Use splitting-limit-capped chunk splitter` on `Sync settings` -> `Performance tweaks`
- Tidied
- Some files have been separated into multiple files to make them more explicit in what they are responsible for.
- 0.23.11:
- Fixed:
- Now we *surely* can set the device name and enable customised synchronisation.
- Unnecessary dialogue update processes have been eliminated.
- Customisation sync no longer stores half-collected files.
- No longer hangs up when removing or renaming files with the `Sync on Save` toggle enabled.
- Improved:
- Customisation sync now performs data deserialization more smoothly.
- New translations have been merged.
- 0.23.10
- Fixed:
- No longer configurations have been locked in the minimal setup.
- 0.23.9 - 0.23.9
- Fixed: - Fixed:
- No longer unexpected parallel replication is performed. - No longer unexpected parallel replication is performed.