One-click backups for AT Protocol

fix: background backups

Turtlepaw 0b4913ae 324ebe0b

+3
bun.lock
··· 23 "@tauri-apps/plugin-autostart": "~2.5.0", 24 "@tauri-apps/plugin-deep-link": "~2.4.0", 25 "@tauri-apps/plugin-fs": "~2.4.0", 26 "@tauri-apps/plugin-opener": "^2.4.0", 27 "@tauri-apps/plugin-process": "~2.3.0", 28 "@tauri-apps/plugin-shell": "~2.3.0", ··· 648 "@tauri-apps/plugin-deep-link": ["@tauri-apps/plugin-deep-link@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-scFldWG5FDqLgbHauS5FtsE563Bo00sqYhhWTYwNzIOZFdOJtNY6tBqzqGJ8I1aehPtEVA0LcTNaq8fmDQbDGg=="], 649 650 "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g=="], 651 652 "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-43VyN8JJtvKWJY72WI/KNZszTpDpzHULFxQs0CJBIYUdCRowQ6Q1feWTDb979N7nldqSuDOaBupZ6wz2nvuWwQ=="], 653
··· 23 "@tauri-apps/plugin-autostart": "~2.5.0", 24 "@tauri-apps/plugin-deep-link": "~2.4.0", 25 "@tauri-apps/plugin-fs": "~2.4.0", 26 + "@tauri-apps/plugin-log": "~2", 27 "@tauri-apps/plugin-opener": "^2.4.0", 28 "@tauri-apps/plugin-process": "~2.3.0", 29 "@tauri-apps/plugin-shell": "~2.3.0", ··· 649 "@tauri-apps/plugin-deep-link": ["@tauri-apps/plugin-deep-link@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-scFldWG5FDqLgbHauS5FtsE563Bo00sqYhhWTYwNzIOZFdOJtNY6tBqzqGJ8I1aehPtEVA0LcTNaq8fmDQbDGg=="], 650 651 "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g=="], 652 + 653 + "@tauri-apps/plugin-log": ["@tauri-apps/plugin-log@2.6.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-gVp3l31akA1Jk2bZsTA0hMFD5/gLe49Nw1btu5lViau0QqgC2XyT79LSwvy7a44ewtQbSexchqIg7oTJKMIbXQ=="], 654 655 "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-43VyN8JJtvKWJY72WI/KNZszTpDpzHULFxQs0CJBIYUdCRowQ6Q1feWTDb979N7nldqSuDOaBupZ6wz2nvuWwQ=="], 656
+1
package.json
··· 29 "@tauri-apps/plugin-autostart": "~2.5.0", 30 "@tauri-apps/plugin-deep-link": "~2.4.0", 31 "@tauri-apps/plugin-fs": "~2.4.0", 32 "@tauri-apps/plugin-opener": "^2.4.0", 33 "@tauri-apps/plugin-process": "~2.3.0", 34 "@tauri-apps/plugin-shell": "~2.3.0",
··· 29 "@tauri-apps/plugin-autostart": "~2.5.0", 30 "@tauri-apps/plugin-deep-link": "~2.4.0", 31 "@tauri-apps/plugin-fs": "~2.4.0", 32 + "@tauri-apps/plugin-log": "~2", 33 "@tauri-apps/plugin-opener": "^2.4.0", 34 "@tauri-apps/plugin-process": "~2.3.0", 35 "@tauri-apps/plugin-shell": "~2.3.0",
+286
src-tauri/Cargo.lock
··· 18 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 20 [[package]] 21 name = "aho-corasick" 22 version = "1.1.3" 23 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 48 checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 49 50 [[package]] 51 name = "android_system_properties" 52 version = "0.1.5" 53 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 70 dependencies = [ 71 "derive_arbitrary", 72 ] 73 74 [[package]] 75 name = "async-broadcast" ··· 216 "tauri-plugin-autostart", 217 "tauri-plugin-deep-link", 218 "tauri-plugin-fs", 219 "tauri-plugin-opener", 220 "tauri-plugin-process", 221 "tauri-plugin-shell", ··· 315 ] 316 317 [[package]] 318 name = "block-buffer" 319 version = "0.10.4" 320 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 355 ] 356 357 [[package]] 358 name = "brotli" 359 version = "8.0.1" 360 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 382 checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 383 384 [[package]] 385 name = "bytemuck" 386 version = "1.23.1" 387 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 991 ] 992 993 [[package]] 994 name = "equivalent" 995 version = "1.0.2" 996 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1050 checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" 1051 dependencies = [ 1052 "simd-adler32", 1053 ] 1054 1055 [[package]] ··· 1127 ] 1128 1129 [[package]] 1130 name = "futf" 1131 version = "0.1.5" 1132 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1536 version = "0.12.3" 1537 source = "registry+https://github.com/rust-lang/crates.io-index" 1538 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1539 1540 [[package]] 1541 name = "hashbrown" ··· 2099 version = "0.4.27" 2100 source = "registry+https://github.com/rust-lang/crates.io-index" 2101 checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 2102 2103 [[package]] 2104 name = "lru-slab" ··· 2302 "proc-macro2", 2303 "quote", 2304 "syn 2.0.104", 2305 ] 2306 2307 [[package]] ··· 2975 ] 2976 2977 [[package]] 2978 name = "quick-xml" 2979 version = "0.38.0" 2980 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3052 version = "5.3.0" 3053 source = "registry+https://github.com/rust-lang/crates.io-index" 3054 checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 3055 3056 [[package]] 3057 name = "rand" ··· 3250 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 3251 3252 [[package]] 3253 name = "reqwest" 3254 version = "0.12.22" 3255 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3305 ] 3306 3307 [[package]] 3308 name = "rust-ini" 3309 version = "0.21.2" 3310 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3315 ] 3316 3317 [[package]] 3318 name = "rustc-demangle" 3319 version = "0.1.25" 3320 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3460 version = "1.2.0" 3461 source = "registry+https://github.com/rust-lang/crates.io-index" 3462 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 3463 3464 [[package]] 3465 name = "selectors" ··· 3723 checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 3724 3725 [[package]] 3726 name = "siphasher" 3727 version = "0.3.11" 3728 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3970 ] 3971 3972 [[package]] 3973 name = "tar" 3974 version = "0.4.44" 3975 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4173 ] 4174 4175 [[package]] 4176 name = "tauri-plugin-opener" 4177 version = "2.4.0" 4178 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4478 dependencies = [ 4479 "deranged", 4480 "itoa", 4481 "num-conv", 4482 "powerfmt", 4483 "serde", 4484 "time-core", ··· 4943 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 4944 4945 [[package]] 4946 name = "utf8_iter" 4947 version = "1.0.4" 4948 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4959 "serde", 4960 "wasm-bindgen", 4961 ] 4962 4963 [[package]] 4964 name = "version-compare" ··· 5726 "windows-core", 5727 "windows-version", 5728 "x11-dl", 5729 ] 5730 5731 [[package]]
··· 18 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 20 [[package]] 21 + name = "ahash" 22 + version = "0.7.8" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 25 + dependencies = [ 26 + "getrandom 0.2.16", 27 + "once_cell", 28 + "version_check", 29 + ] 30 + 31 + [[package]] 32 name = "aho-corasick" 33 version = "1.1.3" 34 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 59 checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 60 61 [[package]] 62 + name = "android_log-sys" 63 + version = "0.3.2" 64 + source = "registry+https://github.com/rust-lang/crates.io-index" 65 + checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" 66 + 67 + [[package]] 68 + name = "android_logger" 69 + version = "0.15.1" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" 72 + dependencies = [ 73 + "android_log-sys", 74 + "env_filter", 75 + "log", 76 + ] 77 + 78 + [[package]] 79 name = "android_system_properties" 80 version = "0.1.5" 81 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 98 dependencies = [ 99 "derive_arbitrary", 100 ] 101 + 102 + [[package]] 103 + name = "arrayvec" 104 + version = "0.7.6" 105 + source = "registry+https://github.com/rust-lang/crates.io-index" 106 + checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 107 108 [[package]] 109 name = "async-broadcast" ··· 250 "tauri-plugin-autostart", 251 "tauri-plugin-deep-link", 252 "tauri-plugin-fs", 253 + "tauri-plugin-log", 254 "tauri-plugin-opener", 255 "tauri-plugin-process", 256 "tauri-plugin-shell", ··· 350 ] 351 352 [[package]] 353 + name = "bitvec" 354 + version = "1.0.1" 355 + source = "registry+https://github.com/rust-lang/crates.io-index" 356 + checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" 357 + dependencies = [ 358 + "funty", 359 + "radium", 360 + "tap", 361 + "wyz", 362 + ] 363 + 364 + [[package]] 365 name = "block-buffer" 366 version = "0.10.4" 367 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 402 ] 403 404 [[package]] 405 + name = "borsh" 406 + version = "1.5.7" 407 + source = "registry+https://github.com/rust-lang/crates.io-index" 408 + checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" 409 + dependencies = [ 410 + "borsh-derive", 411 + "cfg_aliases", 412 + ] 413 + 414 + [[package]] 415 + name = "borsh-derive" 416 + version = "1.5.7" 417 + source = "registry+https://github.com/rust-lang/crates.io-index" 418 + checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" 419 + dependencies = [ 420 + "once_cell", 421 + "proc-macro-crate 3.3.0", 422 + "proc-macro2", 423 + "quote", 424 + "syn 2.0.104", 425 + ] 426 + 427 + [[package]] 428 name = "brotli" 429 version = "8.0.1" 430 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 452 checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 453 454 [[package]] 455 + name = "byte-unit" 456 + version = "5.1.6" 457 + source = "registry+https://github.com/rust-lang/crates.io-index" 458 + checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" 459 + dependencies = [ 460 + "rust_decimal", 461 + "serde", 462 + "utf8-width", 463 + ] 464 + 465 + [[package]] 466 + name = "bytecheck" 467 + version = "0.6.12" 468 + source = "registry+https://github.com/rust-lang/crates.io-index" 469 + checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" 470 + dependencies = [ 471 + "bytecheck_derive", 472 + "ptr_meta", 473 + "simdutf8", 474 + ] 475 + 476 + [[package]] 477 + name = "bytecheck_derive" 478 + version = "0.6.12" 479 + source = "registry+https://github.com/rust-lang/crates.io-index" 480 + checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" 481 + dependencies = [ 482 + "proc-macro2", 483 + "quote", 484 + "syn 1.0.109", 485 + ] 486 + 487 + [[package]] 488 name = "bytemuck" 489 version = "1.23.1" 490 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1094 ] 1095 1096 [[package]] 1097 + name = "env_filter" 1098 + version = "0.1.3" 1099 + source = "registry+https://github.com/rust-lang/crates.io-index" 1100 + checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 1101 + dependencies = [ 1102 + "log", 1103 + "regex", 1104 + ] 1105 + 1106 + [[package]] 1107 name = "equivalent" 1108 version = "1.0.2" 1109 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1163 checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" 1164 dependencies = [ 1165 "simd-adler32", 1166 + ] 1167 + 1168 + [[package]] 1169 + name = "fern" 1170 + version = "0.7.1" 1171 + source = "registry+https://github.com/rust-lang/crates.io-index" 1172 + checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" 1173 + dependencies = [ 1174 + "log", 1175 ] 1176 1177 [[package]] ··· 1249 ] 1250 1251 [[package]] 1252 + name = "funty" 1253 + version = "2.0.0" 1254 + source = "registry+https://github.com/rust-lang/crates.io-index" 1255 + checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" 1256 + 1257 + [[package]] 1258 name = "futf" 1259 version = "0.1.5" 1260 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1664 version = "0.12.3" 1665 source = "registry+https://github.com/rust-lang/crates.io-index" 1666 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1667 + dependencies = [ 1668 + "ahash", 1669 + ] 1670 1671 [[package]] 1672 name = "hashbrown" ··· 2230 version = "0.4.27" 2231 source = "registry+https://github.com/rust-lang/crates.io-index" 2232 checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 2233 + dependencies = [ 2234 + "value-bag", 2235 + ] 2236 2237 [[package]] 2238 name = "lru-slab" ··· 2436 "proc-macro2", 2437 "quote", 2438 "syn 2.0.104", 2439 + ] 2440 + 2441 + [[package]] 2442 + name = "num_threads" 2443 + version = "0.1.7" 2444 + source = "registry+https://github.com/rust-lang/crates.io-index" 2445 + checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" 2446 + dependencies = [ 2447 + "libc", 2448 ] 2449 2450 [[package]] ··· 3118 ] 3119 3120 [[package]] 3121 + name = "ptr_meta" 3122 + version = "0.1.4" 3123 + source = "registry+https://github.com/rust-lang/crates.io-index" 3124 + checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" 3125 + dependencies = [ 3126 + "ptr_meta_derive", 3127 + ] 3128 + 3129 + [[package]] 3130 + name = "ptr_meta_derive" 3131 + version = "0.1.4" 3132 + source = "registry+https://github.com/rust-lang/crates.io-index" 3133 + checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" 3134 + dependencies = [ 3135 + "proc-macro2", 3136 + "quote", 3137 + "syn 1.0.109", 3138 + ] 3139 + 3140 + [[package]] 3141 name = "quick-xml" 3142 version = "0.38.0" 3143 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3215 version = "5.3.0" 3216 source = "registry+https://github.com/rust-lang/crates.io-index" 3217 checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 3218 + 3219 + [[package]] 3220 + name = "radium" 3221 + version = "0.7.0" 3222 + source = "registry+https://github.com/rust-lang/crates.io-index" 3223 + checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" 3224 3225 [[package]] 3226 name = "rand" ··· 3419 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 3420 3421 [[package]] 3422 + name = "rend" 3423 + version = "0.4.2" 3424 + source = "registry+https://github.com/rust-lang/crates.io-index" 3425 + checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" 3426 + dependencies = [ 3427 + "bytecheck", 3428 + ] 3429 + 3430 + [[package]] 3431 name = "reqwest" 3432 version = "0.12.22" 3433 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3483 ] 3484 3485 [[package]] 3486 + name = "rkyv" 3487 + version = "0.7.45" 3488 + source = "registry+https://github.com/rust-lang/crates.io-index" 3489 + checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" 3490 + dependencies = [ 3491 + "bitvec", 3492 + "bytecheck", 3493 + "bytes", 3494 + "hashbrown 0.12.3", 3495 + "ptr_meta", 3496 + "rend", 3497 + "rkyv_derive", 3498 + "seahash", 3499 + "tinyvec", 3500 + "uuid", 3501 + ] 3502 + 3503 + [[package]] 3504 + name = "rkyv_derive" 3505 + version = "0.7.45" 3506 + source = "registry+https://github.com/rust-lang/crates.io-index" 3507 + checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" 3508 + dependencies = [ 3509 + "proc-macro2", 3510 + "quote", 3511 + "syn 1.0.109", 3512 + ] 3513 + 3514 + [[package]] 3515 name = "rust-ini" 3516 version = "0.21.2" 3517 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3522 ] 3523 3524 [[package]] 3525 + name = "rust_decimal" 3526 + version = "1.37.2" 3527 + source = "registry+https://github.com/rust-lang/crates.io-index" 3528 + checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" 3529 + dependencies = [ 3530 + "arrayvec", 3531 + "borsh", 3532 + "bytes", 3533 + "num-traits", 3534 + "rand 0.8.5", 3535 + "rkyv", 3536 + "serde", 3537 + "serde_json", 3538 + ] 3539 + 3540 + [[package]] 3541 name = "rustc-demangle" 3542 version = "0.1.25" 3543 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3683 version = "1.2.0" 3684 source = "registry+https://github.com/rust-lang/crates.io-index" 3685 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 3686 + 3687 + [[package]] 3688 + name = "seahash" 3689 + version = "4.1.0" 3690 + source = "registry+https://github.com/rust-lang/crates.io-index" 3691 + checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 3692 3693 [[package]] 3694 name = "selectors" ··· 3952 checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 3953 3954 [[package]] 3955 + name = "simdutf8" 3956 + version = "0.1.5" 3957 + source = "registry+https://github.com/rust-lang/crates.io-index" 3958 + checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" 3959 + 3960 + [[package]] 3961 name = "siphasher" 3962 version = "0.3.11" 3963 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4205 ] 4206 4207 [[package]] 4208 + name = "tap" 4209 + version = "1.0.1" 4210 + source = "registry+https://github.com/rust-lang/crates.io-index" 4211 + checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 4212 + 4213 + [[package]] 4214 name = "tar" 4215 version = "0.4.44" 4216 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4414 ] 4415 4416 [[package]] 4417 + name = "tauri-plugin-log" 4418 + version = "2.6.0" 4419 + source = "registry+https://github.com/rust-lang/crates.io-index" 4420 + checksum = "a59139183e0907cec1499dddee4e085f5a801dc659efa0848ee224f461371426" 4421 + dependencies = [ 4422 + "android_logger", 4423 + "byte-unit", 4424 + "fern", 4425 + "log", 4426 + "objc2 0.6.1", 4427 + "objc2-foundation 0.3.1", 4428 + "serde", 4429 + "serde_json", 4430 + "serde_repr", 4431 + "swift-rs", 4432 + "tauri", 4433 + "tauri-plugin", 4434 + "thiserror 2.0.12", 4435 + "time", 4436 + ] 4437 + 4438 + [[package]] 4439 name = "tauri-plugin-opener" 4440 version = "2.4.0" 4441 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4741 dependencies = [ 4742 "deranged", 4743 "itoa", 4744 + "libc", 4745 "num-conv", 4746 + "num_threads", 4747 "powerfmt", 4748 "serde", 4749 "time-core", ··· 5208 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 5209 5210 [[package]] 5211 + name = "utf8-width" 5212 + version = "0.1.7" 5213 + source = "registry+https://github.com/rust-lang/crates.io-index" 5214 + checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" 5215 + 5216 + [[package]] 5217 name = "utf8_iter" 5218 version = "1.0.4" 5219 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5230 "serde", 5231 "wasm-bindgen", 5232 ] 5233 + 5234 + [[package]] 5235 + name = "value-bag" 5236 + version = "1.11.1" 5237 + source = "registry+https://github.com/rust-lang/crates.io-index" 5238 + checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" 5239 5240 [[package]] 5241 name = "version-compare" ··· 6003 "windows-core", 6004 "windows-version", 6005 "x11-dl", 6006 + ] 6007 + 6008 + [[package]] 6009 + name = "wyz" 6010 + version = "0.5.1" 6011 + source = "registry+https://github.com/rust-lang/crates.io-index" 6012 + checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" 6013 + dependencies = [ 6014 + "tap", 6015 ] 6016 6017 [[package]]
+1
src-tauri/Cargo.toml
··· 33 chrono = { version = "0.4", features = ["serde"] } 34 tauri-plugin-websocket = "2" 35 tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } 36 37 [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 38 tauri-plugin-autostart = "2"
··· 33 chrono = { version = "0.4", features = ["serde"] } 34 tauri-plugin-websocket = "2" 35 tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } 36 + tauri-plugin-log = "2" 37 38 [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 39 tauri-plugin-autostart = "2"
+54 -29
src-tauri/src/background.rs
··· 1 use serde::{Deserialize, Serialize}; 2 use serde_json::json; 3 use std::sync::Arc; 4 use std::time::{Duration, Instant}; 5 - use tauri::{AppHandle, Emitter}; 6 use tauri_plugin_store::StoreExt; 7 use tokio::sync::Mutex; 8 use tokio::time::sleep; 9 10 #[derive(Debug, Clone, Serialize, Deserialize)] 11 pub struct BackupSettings { 12 - pub frequency: String, // "daily" or "weekly" 13 - pub last_backup_date: Option<String>, 14 } 15 16 pub struct BackgroundScheduler { ··· 35 drop(is_running); 36 37 let is_running = self.is_running.clone(); 38 - let app = self.app.clone(); // <-- assuming it's Arc<App> 39 40 tokio::spawn(async move { 41 - let mut last_check = Instant::now(); 42 - 43 - while *is_running.lock().await { 44 - if last_check.elapsed() >= Duration::from_secs(30 * 60) { 45 - last_check = Instant::now(); 46 47 - if let Err(e) = Self::check_and_perform_backup(app.clone()).await { 48 - eprintln!("Background backup check failed: {}", e); 49 - } 50 } 51 52 - sleep(Duration::from_secs(5 * 60)).await; 53 } 54 }); 55 } ··· 59 *is_running = false; 60 } 61 62 - async fn check_and_perform_backup(app: AppHandle) -> Result<(), Box<dyn std::error::Error>> { 63 // Get settings from store 64 let store = app.store("settings.json")?; 65 let raw_settings: Option<serde_json::Value> = store.get("settings"); 66 67 let value = raw_settings.unwrap_or(json!({ 68 - "frequency": "daily", 69 "last_backup_date": null 70 })); 71 ··· 76 println!("Background: Backup due, starting backup..."); 77 78 // Emit event to frontend to perform backup 79 - app.emit("perform-backup", ())?; 80 - 81 - // Update last backup date 82 - let mut updated_settings = settings; 83 - updated_settings.last_backup_date = Some(chrono::Utc::now().to_rfc3339()); 84 - store.set("settings", json!(updated_settings)); 85 - store.save()?; 86 87 println!("Background: Backup completed"); 88 } ··· 93 async fn should_perform_backup( 94 settings: &BackupSettings, 95 ) -> Result<bool, Box<dyn std::error::Error>> { 96 - if settings.last_backup_date.is_none() { 97 return Ok(true); 98 } 99 100 - let last_backup = 101 - chrono::DateTime::parse_from_rfc3339(&settings.last_backup_date.as_ref().unwrap())?; 102 - let now = chrono::Utc::now(); 103 let time_diff = now.signed_duration_since(last_backup); 104 105 - let required_interval = match settings.frequency.as_str() { 106 "daily" => chrono::Duration::days(1), 107 "weekly" => chrono::Duration::weeks(1), 108 - _ => chrono::Duration::days(1), 109 }; 110 111 Ok(time_diff >= required_interval) 112 } 113 } 114 115 #[tauri::command] 116 - pub async fn start_background_scheduler(app: AppHandle) { 117 let scheduler = BackgroundScheduler::new(app); 118 scheduler.start().await; 119 } 120 121 #[tauri::command]
··· 1 + use chrono::{DateTime, Utc}; 2 use serde::{Deserialize, Serialize}; 3 use serde_json::json; 4 use std::sync::Arc; 5 use std::time::{Duration, Instant}; 6 + use tauri::{App, AppHandle, Emitter, Manager}; 7 use tauri_plugin_store::StoreExt; 8 use tokio::sync::Mutex; 9 use tokio::time::sleep; 10 11 #[derive(Debug, Clone, Serialize, Deserialize)] 12 pub struct BackupSettings { 13 + pub backupFrequency: String, // "daily" or "weekly" 14 + pub lastBackupDate: Option<String>, 15 } 16 17 pub struct BackgroundScheduler { ··· 36 drop(is_running); 37 38 let is_running = self.is_running.clone(); 39 + let app = self.app.clone(); 40 41 tokio::spawn(async move { 42 + loop { 43 + // Your shared flag 44 + if !*is_running.lock().await { 45 + break; 46 + } 47 48 + // Use cloned app 49 + if let Err(e) = Self::check_and_perform_backup(&app).await { 50 + eprintln!("Background backup check failed: {}", e); 51 } 52 53 + sleep(Duration::from_secs(30 * 60)).await; 54 } 55 }); 56 } ··· 60 *is_running = false; 61 } 62 63 + async fn check_and_perform_backup(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>> { 64 + println!("Background: Checking if backup is needed..."); 65 // Get settings from store 66 let store = app.store("settings.json")?; 67 let raw_settings: Option<serde_json::Value> = store.get("settings"); 68 69 let value = raw_settings.unwrap_or(json!({ 70 + "backupFrequency": "daily", 71 "last_backup_date": null 72 })); 73 ··· 78 println!("Background: Backup due, starting backup..."); 79 80 // Emit event to frontend to perform backup 81 + match app.emit("perform-backup", serde_json::json!({})) { 82 + Ok(_) => println!("Event emitted successfully"), 83 + Err(e) => eprintln!("Failed to emit event: {}", e), 84 + } 85 86 println!("Background: Backup completed"); 87 } ··· 92 async fn should_perform_backup( 93 settings: &BackupSettings, 94 ) -> Result<bool, Box<dyn std::error::Error>> { 95 + println!("[DEBUG] Checking if backup should be performed..."); 96 + 97 + if settings.lastBackupDate.is_none() { 98 + println!("[DEBUG] No last_backup_date found; should perform backup."); 99 return Ok(true); 100 } 101 102 + let last_backup_str = settings.lastBackupDate.as_ref().unwrap(); 103 + println!("[DEBUG] Last backup date string: {}", last_backup_str); 104 + 105 + let last_backup = DateTime::parse_from_rfc3339(last_backup_str)?; 106 + let now = Utc::now(); 107 let time_diff = now.signed_duration_since(last_backup); 108 109 + println!("[DEBUG] Current time: {}", now); 110 + println!("[DEBUG] Last backup time: {}", last_backup); 111 + println!( 112 + "[DEBUG] Time since last backup: {} seconds", 113 + time_diff.num_seconds() 114 + ); 115 + 116 + let required_interval = match settings.backupFrequency.as_str() { 117 "daily" => chrono::Duration::days(1), 118 "weekly" => chrono::Duration::weeks(1), 119 + other => { 120 + println!("[DEBUG] Unknown frequency '{}', defaulting to daily", other); 121 + chrono::Duration::days(1) 122 + } 123 }; 124 125 + println!( 126 + "[DEBUG] Required interval (seconds): {}", 127 + required_interval.num_seconds() 128 + ); 129 + println!( 130 + "[DEBUG] Should perform backup? {}", 131 + time_diff >= required_interval 132 + ); 133 + 134 Ok(time_diff >= required_interval) 135 } 136 } 137 138 #[tauri::command] 139 + pub async fn start_background_scheduler(app: AppHandle) -> Result<(), String> { 140 + println!("Starting background scheduler..."); 141 let scheduler = BackgroundScheduler::new(app); 142 scheduler.start().await; 143 + Ok(()) 144 } 145 146 #[tauri::command]
+5 -1
src-tauri/src/lib.rs
··· 7 8 mod background; 9 mod tray; 10 - use background::{start_background_scheduler, stop_background_scheduler}; 11 use tray::create_system_tray; 12 13 #[tauri::command] 14 fn greet(name: &str) -> String { ··· 18 #[cfg_attr(mobile, tauri::mobile_entry_point)] 19 pub fn run() { 20 let builder = tauri::Builder::default() 21 .plugin(tauri_plugin_websocket::init()) 22 .plugin(tauri_plugin_shell::init()) 23 .plugin(tauri_plugin_process::init()) ··· 37 .expect("no main window") 38 .set_focus(); 39 })) 40 .invoke_handler(tauri::generate_handler![ 41 greet, 42 start_background_scheduler,
··· 7 8 mod background; 9 mod tray; 10 + use background::stop_background_scheduler; 11 use tray::create_system_tray; 12 + 13 + use crate::background::{start_background_scheduler, BackgroundScheduler}; 14 15 #[tauri::command] 16 fn greet(name: &str) -> String { ··· 20 #[cfg_attr(mobile, tauri::mobile_entry_point)] 21 pub fn run() { 22 let builder = tauri::Builder::default() 23 + .plugin(tauri_plugin_log::Builder::new().build()) 24 .plugin(tauri_plugin_websocket::init()) 25 .plugin(tauri_plugin_shell::init()) 26 .plugin(tauri_plugin_process::init()) ··· 40 .expect("no main window") 41 .set_focus(); 42 })) 43 + .plugin(tauri_plugin_log::Builder::new().build()) 44 .invoke_handler(tauri::generate_handler![ 45 greet, 46 start_background_scheduler,
+12
src/App.tsx
··· 27 } from "@/components/ui/dialog"; 28 import { Progress } from "./components/ui/progress"; 29 import { MarkdownRenderer } from "./components/ui/markdown-renderer"; 30 31 function AppContent() { 32 const { isLoading, isAuthenticated, profile, client, login, logout, agent } =
··· 27 } from "@/components/ui/dialog"; 28 import { Progress } from "./components/ui/progress"; 29 import { MarkdownRenderer } from "./components/ui/markdown-renderer"; 30 + import { warn, debug, trace, info, error } from "@tauri-apps/plugin-log"; 31 + 32 + function forwardConsole( 33 + fnName: "log" | "debug" | "info" | "warn" | "error", 34 + logger: (message: string) => Promise<void> 35 + ) { 36 + const original = console[fnName]; 37 + console[fnName] = (message) => { 38 + original(message); 39 + logger(message); 40 + }; 41 + } 42 43 function AppContent() { 44 const { isLoading, isAuthenticated, profile, client, login, logout, agent } =
+18 -7
src/lib/backgroundBackup.ts
··· 3 import { BackupAgent } from "./backup"; 4 import { settingsManager } from "./settings"; 5 import { toast } from "sonner"; 6 7 export class BackgroundBackupService { 8 private static instance: BackgroundBackupService; ··· 20 async initialize(): Promise<void> { 21 if (this.isInitialized) return; 22 23 - // Start the background scheduler 24 try { 25 await invoke("start_background_scheduler"); 26 console.log("Background backup scheduler started"); 27 } catch (error) { 28 console.error("Failed to start background scheduler:", error); 29 } 30 - 31 - // Listen for backup events from the background scheduler 32 - await listen("perform-backup", async () => { 33 - console.log("Background backup event received"); 34 - await this.performBackgroundBackup(); 35 - }); 36 37 this.isInitialized = true; 38 }
··· 3 import { BackupAgent } from "./backup"; 4 import { settingsManager } from "./settings"; 5 import { toast } from "sonner"; 6 + import { warn, debug, trace, info, error } from "@tauri-apps/plugin-log"; 7 + import { getCurrentWindow } from "@tauri-apps/api/window"; 8 9 export class BackgroundBackupService { 10 private static instance: BackgroundBackupService; ··· 22 async initialize(): Promise<void> { 23 if (this.isInitialized) return; 24 25 + // Listen for backup events from the background scheduler 26 + const unlisten = await listen("perform-backup", async () => { 27 + console.log("Background backup event received"); 28 + info("Background backup event received"); 29 + await this.performBackgroundBackup(); 30 + }); 31 + 32 + const window = getCurrentWindow(); 33 + const unlistenwb = await window.listen("perform-backup", async () => { 34 + console.log("Background backup event received"); 35 + await this.performBackgroundBackup(); 36 + }); 37 + 38 + console.log("Background backup service initialized"); 39 + 40 + //Start the background scheduler 41 try { 42 await invoke("start_background_scheduler"); 43 console.log("Background backup scheduler started"); 44 } catch (error) { 45 console.error("Failed to start background scheduler:", error); 46 } 47 48 this.isInitialized = true; 49 }
+1
src/routes/Home.tsx
··· 43 DialogTrigger, 44 } from "@/components/ui/dialog"; 45 import { getCurrentWindow } from "@tauri-apps/api/window"; 46 47 export function Home({ 48 profile,
··· 43 DialogTrigger, 44 } from "@/components/ui/dialog"; 45 import { getCurrentWindow } from "@tauri-apps/api/window"; 46 + import { appDataDir } from "@tauri-apps/api/path"; 47 48 export function Home({ 49 profile,