monoidentity 0.21.1 → 0.23.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/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ ISC License
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/dist/+client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export * from "./+common.js";
1
+ export * from "./_common.js";
2
2
  export { getLoginRecognized, relog, getVerification, getStorage, getScopedFS } from "./storage.js";
3
- export type { SyncStrategy } from "./storage/utils-storage.js";
3
+ export type { SyncStrategy } from "./client.js";
4
4
  export { waitForSync } from "./storage/utils-sync.js";
5
5
  export { retrieveVerification } from "./verification-client.js";
6
6
  export { attest as rawAttest } from "./verification/attest.js";
package/dist/+client.js CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./+common.js";
1
+ export * from "./_common.js";
2
2
  export { getLoginRecognized, relog, getVerification, getStorage, getScopedFS } from "./storage.js";
3
3
  export { waitForSync } from "./storage/utils-sync.js";
4
4
  export { retrieveVerification } from "./verification-client.js";
package/dist/+server.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./+common.js";
1
+ export * from "./_common.js";
2
2
  export { useVerification } from "./verification-server.js";
package/dist/+server.js CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./+common.js";
1
+ export * from "./_common.js";
2
2
  export { useVerification } from "./verification-server.js";
@@ -2,17 +2,12 @@
2
2
  import { onDestroy, type Snippet } from "svelte";
3
3
  import { readyUp } from "./readyup.js";
4
4
  import type { Intent } from "./utils-transport.js";
5
- import type { SyncStrategy } from "./storage/utils-storage.js";
6
5
 
7
6
  let {
8
- app,
9
7
  intents,
10
- getSyncStrategy,
11
8
  children,
12
9
  }: {
13
- app: string;
14
10
  intents?: Intent[];
15
- getSyncStrategy: (path: string) => SyncStrategy;
16
11
  children: Snippet;
17
12
  } = $props();
18
13
 
@@ -23,9 +18,7 @@
23
18
 
24
19
  let backup: (() => void) | undefined = $state();
25
20
  readyUp(
26
- app,
27
21
  intents || [],
28
- getSyncStrategy,
29
22
  aborter.signal,
30
23
  (startBackup) =>
31
24
  (backup = () => {
@@ -1,10 +1,7 @@
1
1
  import { type Snippet } from "svelte";
2
2
  import type { Intent } from "./utils-transport.js";
3
- import type { SyncStrategy } from "./storage/utils-storage.js";
4
3
  type $$ComponentProps = {
5
- app: string;
6
4
  intents?: Intent[];
7
- getSyncStrategy: (path: string) => SyncStrategy;
8
5
  children: Snippet;
9
6
  };
10
7
  declare const Monoidentity: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -0,0 +1,8 @@
1
+ export type SyncStrategy =
2
+ | undefined // do not upload or download; will be deleted on next sync unless shouldPersist(key)
3
+ | { mode: "immediate" } // instant sync (e.g., config)
4
+ | { mode: "debounced"; debounceMs: number }; // queued sync (e.g., notes, drawings, chats)
5
+ declare global {
6
+ declare const MONOIDENTITY_APP_ID: string;
7
+ declare const MONOIDENTITY_SYNC_FOR: (path: string) => SyncStrategy;
8
+ }
package/dist/readyup.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import { type Intent } from "./utils-transport.js";
2
- import type { SyncStrategy } from "./storage/utils-storage.js";
3
- export declare const readyUp: (app: string, intents: Intent[], getSyncStrategy: (path: string) => SyncStrategy, signal: AbortSignal, requestBackup: (startBackup: () => void) => void) => void;
2
+ export declare const readyUp: (intents: Intent[], signal: AbortSignal, requestBackup: (startBackup: () => void) => void) => void;
package/dist/readyup.js CHANGED
@@ -2,15 +2,14 @@ import {} from "./utils-transport.js";
2
2
  // import { createLocalStorage } from "./storage/createlocalstorage.js";
3
3
  // import { wrapBackup } from "./storage/wrapbackup.js";
4
4
  // import { wrapCloud } from "./storage/wrapcloud.js";
5
- import { conf, setLoginRecognized } from "./storage.js";
5
+ import { setLoginRecognized } from "./storage.js";
6
6
  import { pullFromLocalBackup } from "./storage/backuplocally-pull.js";
7
7
  import { mountLocalBackupPush } from "./storage/backuplocally-push.js";
8
8
  import { createCloudClient } from "./storage/backupcloud-connection.js";
9
9
  import { mountCloudPull, pullFromCloud } from "./storage/backupcloud-pull.js";
10
10
  import { mountCloudPush } from "./storage/backupcloud-push.js";
11
11
  import { switchToHub } from "./utils-hub.js";
12
- export const readyUp = (app, intents, getSyncStrategy, signal, requestBackup) => {
13
- conf(app);
12
+ export const readyUp = (intents, signal, requestBackup) => {
14
13
  let setup = localStorage["monoidentity-x/setup"]
15
14
  ? JSON.parse(localStorage["monoidentity-x/setup"])
16
15
  : undefined;
@@ -42,7 +41,7 @@ export const readyUp = (app, intents, getSyncStrategy, signal, requestBackup) =>
42
41
  signal.throwIfAborted();
43
42
  if (!dir)
44
43
  return;
45
- mountLocalBackupPush(getSyncStrategy, dir, signal);
44
+ mountLocalBackupPush(dir, signal);
46
45
  })
47
46
  .catch((err) => {
48
47
  console.error("[monoidentity local] pull failed", err);
@@ -50,11 +49,11 @@ export const readyUp = (app, intents, getSyncStrategy, signal, requestBackup) =>
50
49
  }
51
50
  if (setup.method == "cloud") {
52
51
  const client = createCloudClient(setup);
53
- void pullFromCloud(getSyncStrategy, setup, client)
52
+ void pullFromCloud(client)
54
53
  .then(() => {
55
54
  signal.throwIfAborted();
56
- mountCloudPull(getSyncStrategy, setup, client, signal);
57
- mountCloudPush(getSyncStrategy, setup, client, signal);
55
+ mountCloudPull(client, signal);
56
+ mountCloudPush(client, signal);
58
57
  })
59
58
  .catch((err) => {
60
59
  console.error("[monoidentity cloud] pull failed", err);
@@ -1,3 +1,2 @@
1
- export declare const isPlainTextCloudObject: (key: string) => boolean;
2
1
  export declare const encodeCloudContent: (key: string, value: string) => string | Uint8Array<ArrayBuffer>;
3
2
  export declare const decodeCloudContent: (key: string, response: Response) => Promise<string>;
@@ -1,4 +1,4 @@
1
- export const isPlainTextCloudObject = (key) => key.endsWith(".md") || key.endsWith(".devalue");
1
+ const isPlainTextCloudObject = (key) => key.endsWith(".md") || key.endsWith(".devalue");
2
2
  export const encodeCloudContent = (key, value) => {
3
3
  if (isPlainTextCloudObject(key)) {
4
4
  return value;
@@ -1,3 +1,3 @@
1
1
  import type { Bucket } from "../utils-transport.js";
2
- import type { AwsFetch } from "./backupcloud-pull.js";
2
+ export type AwsFetch = (path: string, options?: RequestInit) => Promise<Response>;
3
3
  export declare const createCloudClient: (bucket: Bucket) => AwsFetch;
@@ -4,5 +4,6 @@ export const createCloudClient = (bucket) => {
4
4
  accessKeyId: bucket.accessKeyId,
5
5
  secretAccessKey: bucket.secretAccessKey,
6
6
  });
7
- return (url, options) => awsClient.fetch(url, { ...options, aws: { signQuery: true } });
7
+ const base = bucket.base.endsWith("/") ? bucket.base : bucket.base + "/";
8
+ return (path, options) => awsClient.fetch(base + path, { ...options, aws: { signQuery: true } });
8
9
  };
@@ -1,6 +1,4 @@
1
- import type { Bucket } from "../utils-transport.js";
2
- import { type SyncStrategy } from "./utils-storage.js";
3
- export type AwsFetch = (url: string, options?: RequestInit) => Promise<Response>;
1
+ import type { AwsFetch } from "./backupcloud-connection.js";
4
2
  export declare const setCloudCacheEntry: (key: string, etag: string, content: string) => Promise<void>;
5
- export declare const pullFromCloud: (getSyncStrategy: (path: string) => SyncStrategy, bucket: Bucket, client: AwsFetch) => Promise<void>;
6
- export declare const mountCloudPull: (getSyncStrategy: (path: string) => SyncStrategy, bucket: Bucket, client: AwsFetch, signal: AbortSignal) => () => void;
3
+ export declare const pullFromCloud: (client: AwsFetch) => Promise<void>;
4
+ export declare const mountCloudPull: (client: AwsFetch, signal: AbortSignal) => () => void;
@@ -22,17 +22,17 @@ export const setCloudCacheEntry = async (key, etag, content) => {
22
22
  getCache()[key] = { etag, content };
23
23
  await saveCache();
24
24
  };
25
- const loadFromCloud = async (getSyncStrategy, base, client) => {
26
- const cacheInit = initCache();
27
- const listResp = await client(base);
25
+ const listCloud = async (client) => {
26
+ const listResp = await client("");
28
27
  if (!listResp.ok)
29
28
  throw new Error(`List bucket failed: ${listResp.status}`);
30
29
  const listXml = await listResp.text();
31
- const objects = [...listXml.matchAll(/<Key>(.*?)<\/Key>.*?<ETag>(.*?)<\/ETag>/gs)]
30
+ return [...listXml.matchAll(/<Key>(.*?)<\/Key>.*?<ETag>(.*?)<\/ETag>/gs)]
32
31
  .map((m) => m.slice(1).map((s) => s.replaceAll("&quot;", `"`).replaceAll("&apos;", `'`)))
33
32
  .map(([key, etag]) => ({ key, etag: etag.replaceAll(`"`, "") }))
34
- .filter(({ key }) => getSyncStrategy(key));
35
- await cacheInit;
33
+ .filter(({ key }) => MONOIDENTITY_SYNC_FOR(key));
34
+ };
35
+ const loadFromCloud = async (objects, client) => {
36
36
  const prevCache = getCache();
37
37
  const nextCache = {};
38
38
  const model = {};
@@ -44,7 +44,7 @@ const loadFromCloud = async (getSyncStrategy, base, client) => {
44
44
  return;
45
45
  }
46
46
  console.debug("[monoidentity cloud] loading", key);
47
- const r = await client(`${base}/${key}`);
47
+ const r = await client(key);
48
48
  if (!r.ok)
49
49
  throw new Error(`Fetch ${key} failed: ${r.status}`);
50
50
  const content = await decodeCloudContent(key, r);
@@ -55,8 +55,11 @@ const loadFromCloud = async (getSyncStrategy, base, client) => {
55
55
  await saveCache();
56
56
  return model;
57
57
  };
58
- const _pullFromCloud = async (getSyncStrategy, bucket, client) => {
59
- const remote = await loadFromCloud(getSyncStrategy, bucket.base, client);
58
+ const _pullFromCloud = async (client) => {
59
+ const cachePromise = initCache();
60
+ const objects = await listCloud(client);
61
+ await cachePromise;
62
+ const remote = await loadFromCloud(objects, client);
60
63
  const local = storageClient();
61
64
  for (const key of Object.keys(local)) {
62
65
  if (key in remote)
@@ -71,15 +74,15 @@ const _pullFromCloud = async (getSyncStrategy, bucket, client) => {
71
74
  local[key] = value;
72
75
  }
73
76
  };
74
- export const pullFromCloud = async (getSyncStrategy, bucket, client) => {
75
- const promise = _pullFromCloud(getSyncStrategy, bucket, client);
77
+ export const pullFromCloud = async (client) => {
78
+ const promise = _pullFromCloud(client);
76
79
  addSync("*", promise);
77
80
  await promise;
78
81
  };
79
- export const mountCloudPull = (getSyncStrategy, bucket, client, signal) => {
82
+ export const mountCloudPull = (client, signal) => {
80
83
  signal.throwIfAborted();
81
84
  const syncIntervalId = setInterval(() => {
82
- pullFromCloud(getSyncStrategy, bucket, client).catch((err) => {
85
+ pullFromCloud(client).catch((err) => {
83
86
  console.error("[monoidentity cloud] pull failed", err);
84
87
  });
85
88
  }, 15 * 60 * 1000);
@@ -1,4 +1,2 @@
1
- import type { Bucket } from "../utils-transport.js";
2
- import { type SyncStrategy } from "./utils-storage.js";
3
- import { type AwsFetch } from "./backupcloud-pull.js";
4
- export declare const mountCloudPush: (getSyncStrategy: (path: string) => SyncStrategy, bucket: Bucket, client: AwsFetch, signal: AbortSignal) => () => void;
1
+ import type { AwsFetch } from "./backupcloud-connection.js";
2
+ export declare const mountCloudPush: (client: AwsFetch, signal: AbortSignal) => () => void;
@@ -3,11 +3,10 @@ import { addSync, scheduleSync } from "./utils-sync.js";
3
3
  import { shouldPersist } from "./utils-storage.js";
4
4
  import { setCloudCacheEntry } from "./backupcloud-pull.js";
5
5
  import { encodeCloudContent } from "./_backupcloud.js";
6
- const write = async (key, value, bucket, client) => {
6
+ const write = async (key, value, client) => {
7
7
  console.debug("[monoidentity cloud] saving", key);
8
- const url = `${bucket.base}/${key}`;
9
8
  if (value != undefined) {
10
- const r = await client(url, {
9
+ const r = await client(key, {
11
10
  method: "PUT",
12
11
  headers: { "content-type": "application/octet-stream" },
13
12
  body: encodeCloudContent(key, value),
@@ -20,13 +19,13 @@ const write = async (key, value, bucket, client) => {
20
19
  }
21
20
  return;
22
21
  }
23
- const r = await client(url, { method: "DELETE" });
22
+ const r = await client(key, { method: "DELETE" });
24
23
  if (!r.ok && r.status != 404)
25
24
  throw new Error(`DELETE ${key} failed: ${r.status}`);
26
25
  };
27
- export const mountCloudPush = (getSyncStrategy, bucket, client, signal) => {
26
+ export const mountCloudPush = (client, signal) => {
28
27
  signal.throwIfAborted();
29
- const writeWrapped = async (key, value) => write(key, value, bucket, client).catch((err) => {
28
+ const writeWrapped = async (key, value) => write(key, value, client).catch((err) => {
30
29
  console.error("[monoidentity cloud] save failed", key, err);
31
30
  });
32
31
  const listener = (event) => {
@@ -34,7 +33,7 @@ export const mountCloudPush = (getSyncStrategy, bucket, client, signal) => {
34
33
  if (!fullKey.startsWith("monoidentity/"))
35
34
  return;
36
35
  const key = fullKey.slice("monoidentity/".length);
37
- const strategy = getSyncStrategy(key);
36
+ const strategy = MONOIDENTITY_SYNC_FOR(key);
38
37
  if (!strategy) {
39
38
  if (!shouldPersist(key))
40
39
  console.warn("[monoidentity cloud]", key, "isn't marked to be synced");
@@ -1,2 +1 @@
1
- import { type SyncStrategy } from "./utils-storage.js";
2
- export declare const mountLocalBackupPush: (getSyncStrategy: (path: string) => SyncStrategy, dir: FileSystemDirectoryHandle, signal: AbortSignal) => () => void;
1
+ export declare const mountLocalBackupPush: (dir: FileSystemDirectoryHandle, signal: AbortSignal) => () => void;
@@ -1,7 +1,7 @@
1
1
  import { STORAGE_EVENT } from "./storageclient.svelte.js";
2
2
  import { shouldPersist } from "./utils-storage.js";
3
3
  import { addSync } from "./utils-sync.js";
4
- const saveToDir = (getSyncStrategy, dir) => {
4
+ const saveToDir = (dir) => {
5
5
  let dirCache = {};
6
6
  const getDirCached = async (route) => {
7
7
  let key = "";
@@ -35,7 +35,7 @@ const saveToDir = (getSyncStrategy, dir) => {
35
35
  if (!fullKey.startsWith("monoidentity/"))
36
36
  return;
37
37
  const key = fullKey.slice("monoidentity/".length);
38
- const strategy = getSyncStrategy(key);
38
+ const strategy = MONOIDENTITY_SYNC_FOR(key);
39
39
  if (!strategy) {
40
40
  if (!shouldPersist(key))
41
41
  console.warn("[monoidentity local]", key, "isn't marked to be backed up or saved");
@@ -48,9 +48,9 @@ const saveToDir = (getSyncStrategy, dir) => {
48
48
  removeEventListener(STORAGE_EVENT, listener);
49
49
  };
50
50
  };
51
- export const mountLocalBackupPush = (getSyncStrategy, dir, signal) => {
51
+ export const mountLocalBackupPush = (dir, signal) => {
52
52
  signal.throwIfAborted();
53
- const unmount = saveToDir(getSyncStrategy, dir);
53
+ const unmount = saveToDir(dir);
54
54
  const cleanup = () => {
55
55
  unmount();
56
56
  signal.removeEventListener("abort", onAbort);
@@ -1,7 +1 @@
1
1
  export declare const shouldPersist: (key: string) => boolean;
2
- export type SyncStrategy = undefined | {
3
- mode: "immediate";
4
- } | {
5
- mode: "debounced";
6
- debounceMs: number;
7
- };
package/dist/storage.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export declare const conf: (a: string) => void;
2
1
  export declare const getLoginRecognized: () => {
3
2
  email: string;
4
3
  password: string;
package/dist/storage.js CHANGED
@@ -6,10 +6,6 @@ import { verify } from "@tsndr/cloudflare-worker-jwt";
6
6
  import publicKey from "./verification/public-key.js";
7
7
  import { storageClient } from "./storage/storageclient.svelte.js";
8
8
  import { switchToHub } from "./utils-hub.js";
9
- let app = "unknown";
10
- export const conf = (a) => {
11
- app = a;
12
- };
13
9
  const LOGIN_RECOGNIZED_PATH = ".local/login.encjson";
14
10
  export const getLoginRecognized = () => {
15
11
  const client = storageClient();
@@ -43,7 +39,7 @@ export const setVerification = (jwt) => {
43
39
  client[VERIFICATION_PATH] = jwt;
44
40
  };
45
41
  export const getStorage = (realm) => {
46
- const prefix = `.${realm}/${app}/`;
42
+ const prefix = `.${realm}/${MONOIDENTITY_APP_ID}/`;
47
43
  return storageClient((key) => `${prefix}${key}.devalue`, (key) => (key.startsWith(prefix) ? key.slice(prefix.length, -".devalue".length) : undefined), stringify, parse);
48
44
  };
49
45
  export const getScopedFS = (dir) => storageClient((key) => `${dir}/${key}`, (key) => (key.startsWith(dir + "/") ? key.slice(dir.length + 1) : undefined));
@@ -1 +1 @@
1
- export const canBackup = navigator.userAgent.includes("CrOS") && Boolean(window.showDirectoryPicker);
1
+ export const canBackup = navigator.userAgent.includes("CrOS") && "showDirectoryPicker" in window;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monoidentity",
3
- "version": "0.21.1",
3
+ "version": "0.23.0",
4
4
  "license": "ISC",
5
5
  "repository": "KTibow/monoidentity",
6
6
  "author": {
@@ -44,23 +44,21 @@
44
44
  "@sveltejs/package": "^2.5.7",
45
45
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
46
46
  "@types/wicg-file-system-access": "^2023.10.7",
47
- "knip": "^5.83.1",
48
- "monoserve": "^3.2.3",
47
+ "monoserve": "^3.2.4",
49
48
  "publint": "^0.3.17",
50
49
  "rolldown": "1.0.0-rc.4",
51
50
  "school-districts": "^5.0.1",
52
51
  "svelte": "^5.51.0",
53
52
  "svelte-check": "^4.4.0",
54
53
  "tinyglobby": "^0.2.15",
55
- "typescript": "^5.9.3",
56
- "vite": "^7.3.1"
54
+ "vite": "8.0.0-beta.15"
57
55
  },
58
56
  "keywords": [
59
57
  "svelte"
60
58
  ],
61
59
  "scripts": {
62
60
  "dev": "vite dev",
63
- "build": "pnpm run prepack && pnpm --prefix firebase-functions run build",
61
+ "build": "pnpm run prepack",
64
62
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
65
63
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
66
64
  "knip": "knip"
File without changes
File without changes