monoidentity 0.17.1 → 0.18.0
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.
- package/dist/+client.d.ts +1 -1
- package/dist/+client.js +1 -1
- package/dist/Monoidentity.svelte +3 -10
- package/dist/readyup.d.ts +4 -0
- package/dist/{trackready.js → readyup.js} +14 -7
- package/dist/storage/backupcloud.js +27 -12
- package/dist/storage/backuplocally.js +11 -9
- package/dist/storage/utils-idb.d.ts +1 -0
- package/dist/storage/utils-idb.js +2 -0
- package/dist/storage/utils-storage.d.ts +1 -3
- package/dist/storage/utils-storage.js +1 -1
- package/dist/storage.js +5 -1
- package/package.json +1 -1
- package/dist/trackready.d.ts +0 -3
package/dist/+client.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { getLoginRecognized, relog, getVerification, getStorage, getScopedFS, co
|
|
|
3
3
|
export type { SyncStrategy } from "./storage/utils-storage.js";
|
|
4
4
|
export { retrieveVerification } from "./verification-client.js";
|
|
5
5
|
export { attest as rawAttest } from "./verification/attest.js";
|
|
6
|
-
export {
|
|
6
|
+
export { syncFinished, readyUp } from "./readyup.js";
|
|
7
7
|
export { default as Monoidentity } from "./Monoidentity.svelte";
|
package/dist/+client.js
CHANGED
|
@@ -2,5 +2,5 @@ export * from "./+common.js";
|
|
|
2
2
|
export { getLoginRecognized, relog, getVerification, getStorage, getScopedFS, completeSync, } from "./storage.js";
|
|
3
3
|
export { retrieveVerification } from "./verification-client.js";
|
|
4
4
|
export { attest as rawAttest } from "./verification/attest.js";
|
|
5
|
-
export {
|
|
5
|
+
export { syncFinished, readyUp } from "./readyup.js";
|
|
6
6
|
export { default as Monoidentity } from "./Monoidentity.svelte";
|
package/dist/Monoidentity.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
|
-
import {
|
|
3
|
+
import { readyUp } from "./readyup.js";
|
|
4
4
|
import type { Intent } from "./utils-transport.js";
|
|
5
5
|
import type { SyncStrategy } from "./storage/utils-storage.js";
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
} = $props();
|
|
18
18
|
|
|
19
19
|
let backup: (() => void) | undefined = $state();
|
|
20
|
-
|
|
20
|
+
readyUp(
|
|
21
21
|
app,
|
|
22
22
|
intents || [],
|
|
23
23
|
getSyncStrategy,
|
|
@@ -35,11 +35,7 @@
|
|
|
35
35
|
<button class="primary" onclick={yes}>Connect</button>
|
|
36
36
|
{/snippet}
|
|
37
37
|
|
|
38
|
-
{
|
|
39
|
-
<p class="center">Setting up</p>
|
|
40
|
-
{:then}
|
|
41
|
-
{@render children()}
|
|
42
|
-
{/await}
|
|
38
|
+
{@render children()}
|
|
43
39
|
{#if backup}
|
|
44
40
|
<div class="backup toast">
|
|
45
41
|
{@render backupUI(backup, () => (backup = undefined))}
|
|
@@ -88,7 +84,4 @@
|
|
|
88
84
|
top: 1rem;
|
|
89
85
|
z-index: 1000;
|
|
90
86
|
}
|
|
91
|
-
.center {
|
|
92
|
-
margin: auto;
|
|
93
|
-
}
|
|
94
87
|
</style>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Intent } from "./utils-transport.js";
|
|
2
|
+
import type { SyncStrategy } from "./storage/utils-storage.js";
|
|
3
|
+
export declare const syncFinished: Promise<void>;
|
|
4
|
+
export declare const readyUp: (app: string, intents: Intent[], getSyncStrategy: (path: string) => SyncStrategy, requestBackup: (startBackup: () => void) => void) => void;
|
|
@@ -6,7 +6,11 @@ import { conf, setLoginRecognized } from "./storage.js";
|
|
|
6
6
|
import { backupLocally } from "./storage/backuplocally.js";
|
|
7
7
|
import { backupCloud } from "./storage/backupcloud.js";
|
|
8
8
|
import { switchToHub } from "./utils-hub.js";
|
|
9
|
-
|
|
9
|
+
let resolveSyncFinished;
|
|
10
|
+
export const syncFinished = new Promise((resolve) => {
|
|
11
|
+
resolveSyncFinished = resolve;
|
|
12
|
+
});
|
|
13
|
+
export const readyUp = (app, intents, getSyncStrategy, requestBackup) => {
|
|
10
14
|
conf(app);
|
|
11
15
|
let setup = localStorage["monoidentity-x/setup"]
|
|
12
16
|
? JSON.parse(localStorage["monoidentity-x/setup"])
|
|
@@ -27,15 +31,18 @@ export const trackReady = async (app, intents, getSyncStrategy, requestBackup) =
|
|
|
27
31
|
if (!setup) {
|
|
28
32
|
switchToHub([{ storage: true }, ...intents]);
|
|
29
33
|
}
|
|
30
|
-
if (setup.method == "localStorage") {
|
|
31
|
-
await backupLocally(getSyncStrategy, requestBackup);
|
|
32
|
-
}
|
|
33
|
-
if (setup.method == "cloud") {
|
|
34
|
-
await backupCloud(getSyncStrategy, setup);
|
|
35
|
-
}
|
|
36
34
|
for (const provision of provisions) {
|
|
37
35
|
if ("createLoginRecognized" in provision) {
|
|
38
36
|
setLoginRecognized(provision.createLoginRecognized);
|
|
39
37
|
}
|
|
40
38
|
}
|
|
39
|
+
(async () => {
|
|
40
|
+
if (setup.method == "localStorage") {
|
|
41
|
+
await backupLocally(getSyncStrategy, requestBackup);
|
|
42
|
+
}
|
|
43
|
+
if (setup.method == "cloud") {
|
|
44
|
+
await backupCloud(getSyncStrategy, setup);
|
|
45
|
+
}
|
|
46
|
+
resolveSyncFinished();
|
|
47
|
+
})();
|
|
41
48
|
};
|
|
@@ -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}`);
|
|
@@ -12,8 +29,9 @@ const loadFromCloud = async (getSyncStrategy, base, client) => {
|
|
|
12
29
|
const objects = [...listXml.matchAll(/<Key>(.*?)<\/Key>.*?<ETag>(.*?)<\/ETag>/gs)]
|
|
13
30
|
.map((m) => m.slice(1).map((s) => s.replaceAll(""", `"`).replaceAll("'", `'`)))
|
|
14
31
|
.map(([key, etag]) => ({ key, etag: etag.replaceAll(`"`, "") }))
|
|
15
|
-
.filter(({ key }) => getSyncStrategy(key)
|
|
16
|
-
|
|
32
|
+
.filter(({ key }) => getSyncStrategy(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
|
-
|
|
63
|
+
cache = nextCache;
|
|
64
|
+
saveCache();
|
|
46
65
|
return model;
|
|
47
66
|
};
|
|
48
67
|
const syncFromCloud = async (getSyncStrategy, bucket, client) => {
|
|
@@ -72,7 +91,7 @@ export const backupCloud = async (getSyncStrategy, bucket) => {
|
|
|
72
91
|
// Continuous sync: mirror local changes to cloud
|
|
73
92
|
const write = async (key, value) => {
|
|
74
93
|
const strategy = getSyncStrategy(key);
|
|
75
|
-
if (strategy
|
|
94
|
+
if (!strategy) {
|
|
76
95
|
if (!shouldPersist(key))
|
|
77
96
|
console.warn("[monoidentity cloud]", key, "isn't marked to be backed up or saved");
|
|
78
97
|
return;
|
|
@@ -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) => {
|
|
@@ -115,7 +130,7 @@ export const backupCloud = async (getSyncStrategy, bucket) => {
|
|
|
115
130
|
return;
|
|
116
131
|
const key = fullKey.slice("monoidentity/".length);
|
|
117
132
|
const strategy = getSyncStrategy(key);
|
|
118
|
-
if (strategy
|
|
133
|
+
if (!strategy)
|
|
119
134
|
return;
|
|
120
135
|
if (strategy.mode == "immediate") {
|
|
121
136
|
addToSync(writeWrapped(key, event.detail.value));
|
|
@@ -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 = {};
|
|
@@ -39,7 +42,7 @@ const saveToDir = (getSyncStrategy, dir) => {
|
|
|
39
42
|
return;
|
|
40
43
|
const key = fullKey.slice("monoidentity/".length);
|
|
41
44
|
const strategy = getSyncStrategy(key);
|
|
42
|
-
if (strategy
|
|
45
|
+
if (!strategy) {
|
|
43
46
|
if (!shouldPersist(key))
|
|
44
47
|
console.warn("[monoidentity backup]", key, "isn't marked to be backed up or saved");
|
|
45
48
|
return;
|
|
@@ -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) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const store: import("idb-keyval").UseStore;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const shouldPersist = (key) => key.
|
|
1
|
+
export const shouldPersist = (key) => key.startsWith(".cache/") || key.startsWith(".local/");
|
|
2
2
|
const syncQueue = {};
|
|
3
3
|
export const enqueueSync = (key, debounceMs, sync) => {
|
|
4
4
|
// Cancel existing timeout if any
|
package/dist/storage.js
CHANGED
|
@@ -15,9 +15,13 @@ export const addToSync = (p) => {
|
|
|
15
15
|
syncPromise = syncPromise.then(() => p);
|
|
16
16
|
};
|
|
17
17
|
export const completeSync = () => syncPromise;
|
|
18
|
-
const LOGIN_RECOGNIZED_PATH = ".
|
|
18
|
+
const LOGIN_RECOGNIZED_PATH = ".local/login.encjson";
|
|
19
19
|
export const getLoginRecognized = () => {
|
|
20
20
|
const client = storageClient();
|
|
21
|
+
if (client[".core/login.encjson"]) {
|
|
22
|
+
client[LOGIN_RECOGNIZED_PATH] = client[".core/login.encjson"];
|
|
23
|
+
delete client[".core/login.encjson"];
|
|
24
|
+
}
|
|
21
25
|
const login = client[LOGIN_RECOGNIZED_PATH];
|
|
22
26
|
if (!login)
|
|
23
27
|
throw new Error("No login found");
|
package/package.json
CHANGED
package/dist/trackready.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { type Intent } from "./utils-transport.js";
|
|
2
|
-
import type { SyncStrategy } from "./storage/utils-storage.js";
|
|
3
|
-
export declare const trackReady: (app: string, intents: Intent[], getSyncStrategy: (path: string) => SyncStrategy, requestBackup: (startBackup: () => void) => void) => Promise<void>;
|