monoidentity 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2,9 +2,26 @@ import { AwsClient } from "aws4fetch";
|
|
|
2
2
|
import { storageClient, STORAGE_EVENT } from "./storageclient.svelte.js";
|
|
3
3
|
import { addToSync } from "../storage.js";
|
|
4
4
|
import { shouldPersist, enqueueSync } from "./utils-storage.js";
|
|
5
|
-
|
|
5
|
+
import { get, set } from "idb-keyval";
|
|
6
|
+
import { store } from "./utils-idb.js";
|
|
7
|
+
const CLOUD_CACHE_KEY = "cloud-cache";
|
|
6
8
|
let unmount;
|
|
9
|
+
let cache;
|
|
10
|
+
const initCache = async () => {
|
|
11
|
+
cache = (await get(CLOUD_CACHE_KEY, store)) || {};
|
|
12
|
+
};
|
|
13
|
+
const getCache = () => {
|
|
14
|
+
if (!cache)
|
|
15
|
+
throw new Error("Cache not initialized");
|
|
16
|
+
return cache;
|
|
17
|
+
};
|
|
18
|
+
const saveCache = async () => {
|
|
19
|
+
if (!cache)
|
|
20
|
+
throw new Error("Cache not initialized");
|
|
21
|
+
await set(CLOUD_CACHE_KEY, cache, store);
|
|
22
|
+
};
|
|
7
23
|
const loadFromCloud = async (getSyncStrategy, base, client) => {
|
|
24
|
+
const cachePromise = initCache();
|
|
8
25
|
const listResp = await client.fetch(base);
|
|
9
26
|
if (!listResp.ok)
|
|
10
27
|
throw new Error(`List bucket failed: ${listResp.status}`);
|
|
@@ -13,7 +30,8 @@ const loadFromCloud = async (getSyncStrategy, base, client) => {
|
|
|
13
30
|
.map((m) => m.slice(1).map((s) => s.replaceAll(""", `"`).replaceAll("'", `'`)))
|
|
14
31
|
.map(([key, etag]) => ({ key, etag: etag.replaceAll(`"`, "") }))
|
|
15
32
|
.filter(({ key }) => getSyncStrategy(key).mode != "none");
|
|
16
|
-
|
|
33
|
+
await cachePromise;
|
|
34
|
+
const prevCache = getCache();
|
|
17
35
|
const nextCache = {};
|
|
18
36
|
const model = {};
|
|
19
37
|
await Promise.all(objects.map(async ({ key, etag }) => {
|
|
@@ -42,7 +60,8 @@ const loadFromCloud = async (getSyncStrategy, base, client) => {
|
|
|
42
60
|
model[key] = content;
|
|
43
61
|
nextCache[key] = { etag, content };
|
|
44
62
|
}));
|
|
45
|
-
|
|
63
|
+
cache = nextCache;
|
|
64
|
+
saveCache();
|
|
46
65
|
return model;
|
|
47
66
|
};
|
|
48
67
|
const syncFromCloud = async (getSyncStrategy, bucket, client) => {
|
|
@@ -91,9 +110,8 @@ export const backupCloud = async (getSyncStrategy, bucket) => {
|
|
|
91
110
|
// Update cache
|
|
92
111
|
const etag = r.headers.get("etag")?.replaceAll('"', "");
|
|
93
112
|
if (etag) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
localStorage[CLOUD_CACHE_KEY] = JSON.stringify(cache);
|
|
113
|
+
getCache()[key] = { etag, content: value };
|
|
114
|
+
saveCache();
|
|
97
115
|
}
|
|
98
116
|
}
|
|
99
117
|
else {
|
|
@@ -101,9 +119,6 @@ export const backupCloud = async (getSyncStrategy, bucket) => {
|
|
|
101
119
|
const r = await client.fetch(url, { method: "DELETE" });
|
|
102
120
|
if (!r.ok && r.status != 404)
|
|
103
121
|
throw new Error(`DELETE ${key} failed: ${r.status}`);
|
|
104
|
-
const cache = JSON.parse(localStorage[CLOUD_CACHE_KEY] || "{}");
|
|
105
|
-
delete cache[key];
|
|
106
|
-
localStorage[CLOUD_CACHE_KEY] = JSON.stringify(cache);
|
|
107
122
|
}
|
|
108
123
|
};
|
|
109
124
|
const writeWrapped = async (key, value) => write(key, value).catch((err) => {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { get, set } from "idb-keyval";
|
|
2
2
|
import { STORAGE_EVENT, storageClient } from "./storageclient.svelte.js";
|
|
3
3
|
import { canBackup } from "../utils-localstorage.js";
|
|
4
4
|
import { shouldPersist } from "./utils-storage.js";
|
|
5
|
+
import { store } from "./utils-idb.js";
|
|
6
|
+
const TOGGLE_KEY = "monoidentity-x/local-backup";
|
|
7
|
+
const HANDLE_KEY = "backup-handle";
|
|
5
8
|
let unmount;
|
|
6
9
|
const saveToDir = (getSyncStrategy, dir) => {
|
|
7
10
|
let dirCache = {};
|
|
@@ -55,22 +58,21 @@ const saveToDir = (getSyncStrategy, dir) => {
|
|
|
55
58
|
export const backupLocally = async (getSyncStrategy, requestBackup) => {
|
|
56
59
|
if (!canBackup)
|
|
57
60
|
return;
|
|
58
|
-
if (localStorage[
|
|
61
|
+
if (localStorage[TOGGLE_KEY] == "off")
|
|
59
62
|
return;
|
|
60
63
|
unmount?.();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const dir = await get("backup", handles);
|
|
64
|
+
if (localStorage[TOGGLE_KEY] == "on") {
|
|
65
|
+
const dir = await get(HANDLE_KEY, store);
|
|
64
66
|
if (!dir)
|
|
65
67
|
throw new Error("No backup handle found");
|
|
66
68
|
unmount = saveToDir(getSyncStrategy, dir);
|
|
67
69
|
}
|
|
68
70
|
else {
|
|
69
|
-
localStorage[
|
|
71
|
+
localStorage[TOGGLE_KEY] = "off";
|
|
70
72
|
requestBackup(async () => {
|
|
71
73
|
const dir = await showDirectoryPicker({ mode: "readwrite" });
|
|
72
|
-
await set(
|
|
73
|
-
localStorage[
|
|
74
|
+
await set(HANDLE_KEY, dir, store);
|
|
75
|
+
localStorage[TOGGLE_KEY] = "on";
|
|
74
76
|
// Restore from backup
|
|
75
77
|
const backup = {};
|
|
76
78
|
const traverse = async (d, path) => {
|
|
@@ -65,8 +65,13 @@ export const storageClient = (prefix, unprefix, serialize, deserialize) => {
|
|
|
65
65
|
key = prefix(key);
|
|
66
66
|
if (serialize)
|
|
67
67
|
value = serialize(value);
|
|
68
|
-
localStorage[key]
|
|
69
|
-
|
|
68
|
+
if (localStorage[key] != value) {
|
|
69
|
+
localStorage[key] = value;
|
|
70
|
+
announce(key, value);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.debug("[monoidentity storage] noop for", key);
|
|
74
|
+
}
|
|
70
75
|
return true;
|
|
71
76
|
},
|
|
72
77
|
deleteProperty(_, key) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const store: import("idb-keyval").UseStore;
|