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
- const CLOUD_CACHE_KEY = "monoidentity-x/cloud-cache";
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
- const prevCache = JSON.parse(localStorage[CLOUD_CACHE_KEY] || "{}");
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
- localStorage[CLOUD_CACHE_KEY] = JSON.stringify(nextCache);
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
- const cache = JSON.parse(localStorage[CLOUD_CACHE_KEY] || "{}");
95
- cache[key] = { etag, content: value };
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 { createStore, get, set } from "idb-keyval";
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["monoidentity-x/backup"] == "off")
61
+ if (localStorage[TOGGLE_KEY] == "off")
59
62
  return;
60
63
  unmount?.();
61
- const handles = createStore("monoidentity-x", "handles");
62
- if (localStorage["monoidentity-x/backup"] == "on") {
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["monoidentity-x/backup"] = "off";
71
+ localStorage[TOGGLE_KEY] = "off";
70
72
  requestBackup(async () => {
71
73
  const dir = await showDirectoryPicker({ mode: "readwrite" });
72
- await set("backup", dir, handles);
73
- localStorage["monoidentity-x/backup"] = "on";
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] = value;
69
- announce(key, value);
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;
@@ -0,0 +1,2 @@
1
+ import { createStore } from "idb-keyval";
2
+ export const store = createStore("monoidentity-x", "keyval");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monoidentity",
3
- "version": "0.17.0",
3
+ "version": "0.17.2",
4
4
  "license": "ISC",
5
5
  "repository": "KTibow/monoidentity",
6
6
  "author": {