@bobfrankston/mailx-store-web 0.1.5
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/android-bootstrap.d.ts +16 -0
- package/android-bootstrap.d.ts.map +1 -0
- package/android-bootstrap.js +1438 -0
- package/android-bootstrap.js.map +1 -0
- package/android-bootstrap.ts +1450 -0
- package/db.d.ts +146 -0
- package/db.d.ts.map +1 -0
- package/db.js +725 -0
- package/db.js.map +1 -0
- package/db.ts +831 -0
- package/gmail-api-web.d.ts +11 -0
- package/gmail-api-web.d.ts.map +1 -0
- package/gmail-api-web.js +11 -0
- package/gmail-api-web.js.map +1 -0
- package/gmail-api-web.ts +11 -0
- package/imap-web-provider.d.ts +33 -0
- package/imap-web-provider.d.ts.map +1 -0
- package/imap-web-provider.js +140 -0
- package/imap-web-provider.js.map +1 -0
- package/imap-web-provider.ts +156 -0
- package/index.d.ts +10 -0
- package/index.d.ts.map +1 -0
- package/index.js +10 -0
- package/index.js.map +1 -0
- package/index.ts +10 -0
- package/main-thread-host.d.ts +15 -0
- package/main-thread-host.d.ts.map +1 -0
- package/main-thread-host.js +292 -0
- package/main-thread-host.js.map +1 -0
- package/main-thread-host.ts +322 -0
- package/package.json +41 -0
- package/provider-types.d.ts +7 -0
- package/provider-types.d.ts.map +1 -0
- package/provider-types.js +7 -0
- package/provider-types.js.map +1 -0
- package/provider-types.ts +7 -0
- package/sql-wasm-esm.js +10 -0
- package/sql.js.d.ts +29 -0
- package/sync-manager.d.ts +68 -0
- package/sync-manager.d.ts.map +1 -0
- package/sync-manager.js +506 -0
- package/sync-manager.js.map +1 -0
- package/sync-manager.ts +508 -0
- package/tsconfig.json +10 -0
- package/web-jsonrpc.d.ts +20 -0
- package/web-jsonrpc.d.ts.map +1 -0
- package/web-jsonrpc.js +112 -0
- package/web-jsonrpc.js.map +1 -0
- package/web-jsonrpc.ts +126 -0
- package/web-message-store.d.ts +16 -0
- package/web-message-store.d.ts.map +1 -0
- package/web-message-store.js +89 -0
- package/web-message-store.js.map +1 -0
- package/web-message-store.ts +97 -0
- package/web-service.d.ts +136 -0
- package/web-service.d.ts.map +1 -0
- package/web-service.js +687 -0
- package/web-service.js.map +1 -0
- package/web-service.ts +754 -0
- package/web-settings.d.ts +91 -0
- package/web-settings.d.ts.map +1 -0
- package/web-settings.js +518 -0
- package/web-settings.js.map +1 -0
- package/web-settings.ts +547 -0
- package/worker-bundle.js +6838 -0
- package/worker-entry.d.ts +8 -0
- package/worker-entry.d.ts.map +1 -0
- package/worker-entry.js +218 -0
- package/worker-entry.js.map +1 -0
- package/worker-entry.ts +245 -0
- package/worker-tcp-transport.d.ts +28 -0
- package/worker-tcp-transport.d.ts.map +1 -0
- package/worker-tcp-transport.js +98 -0
- package/worker-tcp-transport.js.map +1 -0
- package/worker-tcp-transport.ts +101 -0
package/web-jsonrpc.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC dispatcher for WebMailxService.
|
|
3
|
+
* Maps mailxapi action names to WebMailxService method calls.
|
|
4
|
+
* Same dispatch table as desktop jsonrpc.ts but adapted for async settings.
|
|
5
|
+
*/
|
|
6
|
+
/** Dispatch an incoming mailxapi call to the appropriate WebMailxService method */
|
|
7
|
+
export async function dispatch(svc, req) {
|
|
8
|
+
const { _action, _cbid, ...params } = req;
|
|
9
|
+
try {
|
|
10
|
+
const result = await dispatchAction(svc, _action, params);
|
|
11
|
+
return { _cbid, result };
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
return { _cbid, error: e.message || String(e) };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function dispatchAction(svc, action, p) {
|
|
18
|
+
switch (action) {
|
|
19
|
+
case "getAccounts":
|
|
20
|
+
return svc.getAccounts();
|
|
21
|
+
case "getFolders":
|
|
22
|
+
return svc.getFolders(p.accountId);
|
|
23
|
+
case "getMessages":
|
|
24
|
+
return svc.getMessages(p.accountId, p.folderId, p.page, p.pageSize);
|
|
25
|
+
case "getUnifiedInbox":
|
|
26
|
+
return svc.getUnifiedInbox(p.page || 1, p.pageSize || 50);
|
|
27
|
+
case "getMessage":
|
|
28
|
+
return svc.getMessage(p.accountId, p.uid, p.allowRemote, p.folderId);
|
|
29
|
+
case "updateFlags":
|
|
30
|
+
await svc.updateFlags(p.accountId, p.uid, p.flags);
|
|
31
|
+
return { ok: true };
|
|
32
|
+
case "deleteMessage":
|
|
33
|
+
await svc.deleteMessage(p.accountId, p.uid);
|
|
34
|
+
return { ok: true };
|
|
35
|
+
case "deleteMessages":
|
|
36
|
+
await svc.deleteMessages(p.accountId, p.uids);
|
|
37
|
+
return { ok: true, count: p.uids.length };
|
|
38
|
+
case "undeleteMessage":
|
|
39
|
+
await svc.undeleteMessage(p.accountId, p.uid, p.folderId);
|
|
40
|
+
return { ok: true };
|
|
41
|
+
case "moveMessage":
|
|
42
|
+
await svc.moveMessage(p.accountId, p.uid, p.targetFolderId, p.targetAccountId);
|
|
43
|
+
return { ok: true };
|
|
44
|
+
case "moveMessages":
|
|
45
|
+
await svc.moveMessages(p.accountId, p.uids, p.targetFolderId);
|
|
46
|
+
return { ok: true, count: p.uids.length };
|
|
47
|
+
case "markFolderRead":
|
|
48
|
+
svc.markFolderRead(p.folderId);
|
|
49
|
+
return { ok: true };
|
|
50
|
+
case "sendMessage":
|
|
51
|
+
await svc.send(p);
|
|
52
|
+
return { ok: true };
|
|
53
|
+
case "saveDraft":
|
|
54
|
+
return svc.saveDraft(p.accountId, p.subject, p.bodyHtml, p.bodyText, p.to, p.cc, p.previousDraftUid, p.draftId);
|
|
55
|
+
case "deleteDraft":
|
|
56
|
+
await svc.deleteDraft(p.accountId, p.draftUid);
|
|
57
|
+
return { ok: true };
|
|
58
|
+
case "syncAll":
|
|
59
|
+
await svc.syncAll();
|
|
60
|
+
return { ok: true };
|
|
61
|
+
case "syncAccount":
|
|
62
|
+
await svc.syncAccount(p.accountId);
|
|
63
|
+
return { ok: true };
|
|
64
|
+
case "getSyncPending":
|
|
65
|
+
return svc.getSyncPending();
|
|
66
|
+
case "reauthenticate":
|
|
67
|
+
return { ok: await svc.reauthenticate(p.accountId) };
|
|
68
|
+
case "searchMessages":
|
|
69
|
+
return svc.search(p.query, p.page, p.pageSize, p.scope, p.accountId, p.folderId);
|
|
70
|
+
case "searchContacts":
|
|
71
|
+
return svc.searchContacts(p.query);
|
|
72
|
+
case "listContacts":
|
|
73
|
+
return svc.listContacts(p.query || "", p.page || 1, p.pageSize || 100);
|
|
74
|
+
case "upsertContact":
|
|
75
|
+
return svc.upsertContact(p.name || "", p.email);
|
|
76
|
+
case "deleteContact":
|
|
77
|
+
return svc.deleteContact(p.email);
|
|
78
|
+
case "addContact":
|
|
79
|
+
return svc.addContact(p.name || "", p.email);
|
|
80
|
+
case "getSettings":
|
|
81
|
+
return svc.getSettings();
|
|
82
|
+
case "saveSettingsData":
|
|
83
|
+
await svc.saveSettingsData(p);
|
|
84
|
+
return { ok: true };
|
|
85
|
+
case "allowRemoteContent":
|
|
86
|
+
await svc.allowRemoteContent(p.type, p.value);
|
|
87
|
+
return { ok: true };
|
|
88
|
+
case "flagSenderOrDomain":
|
|
89
|
+
return await svc.flagSenderOrDomain(p.type, p.value);
|
|
90
|
+
case "getPriorityLists":
|
|
91
|
+
return await svc.getPriorityLists();
|
|
92
|
+
case "setPrioritySender":
|
|
93
|
+
await svc.setPrioritySender(p.email, !!p.value, p.name);
|
|
94
|
+
return { ok: true };
|
|
95
|
+
case "setPriorityDomain":
|
|
96
|
+
await svc.setPriorityDomain(p.domain, !!p.value);
|
|
97
|
+
return { ok: true };
|
|
98
|
+
case "getVersion":
|
|
99
|
+
return { version: "1.0.0-android", theme: "system", storage: svc.getStorageInfo(), platform: "android" };
|
|
100
|
+
case "getAutocompleteSettings":
|
|
101
|
+
return svc.getAutocompleteSettings();
|
|
102
|
+
case "saveAutocompleteSettings":
|
|
103
|
+
await svc.saveAutocompleteSettings(p);
|
|
104
|
+
return { ok: true };
|
|
105
|
+
case "resetStore":
|
|
106
|
+
await svc.resetStore();
|
|
107
|
+
return { ok: true };
|
|
108
|
+
default:
|
|
109
|
+
throw new Error(`Unknown action: ${action}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=web-jsonrpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-jsonrpc.js","sourceRoot":"","sources":["web-jsonrpc.ts"],"names":[],"mappings":"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"}
|
package/web-jsonrpc.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC dispatcher for WebMailxService.
|
|
3
|
+
* Maps mailxapi action names to WebMailxService method calls.
|
|
4
|
+
* Same dispatch table as desktop jsonrpc.ts but adapted for async settings.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
type ServiceLike = Record<string, (...args: any[]) => any>;
|
|
8
|
+
|
|
9
|
+
export interface RpcRequest {
|
|
10
|
+
_action: string;
|
|
11
|
+
_cbid: string;
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface RpcResponse {
|
|
16
|
+
_cbid: string;
|
|
17
|
+
result?: any;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Dispatch an incoming mailxapi call to the appropriate WebMailxService method */
|
|
22
|
+
export async function dispatch(svc: ServiceLike, req: RpcRequest): Promise<RpcResponse> {
|
|
23
|
+
const { _action, _cbid, ...params } = req;
|
|
24
|
+
try {
|
|
25
|
+
const result = await dispatchAction(svc, _action, params);
|
|
26
|
+
return { _cbid, result };
|
|
27
|
+
} catch (e: any) {
|
|
28
|
+
return { _cbid, error: e.message || String(e) };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function dispatchAction(svc: ServiceLike, action: string, p: Record<string, any>): Promise<any> {
|
|
33
|
+
switch (action) {
|
|
34
|
+
case "getAccounts":
|
|
35
|
+
return svc.getAccounts();
|
|
36
|
+
case "getFolders":
|
|
37
|
+
return svc.getFolders(p.accountId);
|
|
38
|
+
case "getMessages":
|
|
39
|
+
return svc.getMessages(p.accountId, p.folderId, p.page, p.pageSize);
|
|
40
|
+
case "getUnifiedInbox":
|
|
41
|
+
return svc.getUnifiedInbox(p.page || 1, p.pageSize || 50);
|
|
42
|
+
case "getMessage":
|
|
43
|
+
return svc.getMessage(p.accountId, p.uid, p.allowRemote, p.folderId);
|
|
44
|
+
case "updateFlags":
|
|
45
|
+
await svc.updateFlags(p.accountId, p.uid, p.flags);
|
|
46
|
+
return { ok: true };
|
|
47
|
+
case "deleteMessage":
|
|
48
|
+
await svc.deleteMessage(p.accountId, p.uid);
|
|
49
|
+
return { ok: true };
|
|
50
|
+
case "deleteMessages":
|
|
51
|
+
await svc.deleteMessages(p.accountId, p.uids);
|
|
52
|
+
return { ok: true, count: p.uids.length };
|
|
53
|
+
case "undeleteMessage":
|
|
54
|
+
await svc.undeleteMessage(p.accountId, p.uid, p.folderId);
|
|
55
|
+
return { ok: true };
|
|
56
|
+
case "moveMessage":
|
|
57
|
+
await svc.moveMessage(p.accountId, p.uid, p.targetFolderId, p.targetAccountId);
|
|
58
|
+
return { ok: true };
|
|
59
|
+
case "moveMessages":
|
|
60
|
+
await svc.moveMessages(p.accountId, p.uids, p.targetFolderId);
|
|
61
|
+
return { ok: true, count: p.uids.length };
|
|
62
|
+
case "markFolderRead":
|
|
63
|
+
svc.markFolderRead(p.folderId);
|
|
64
|
+
return { ok: true };
|
|
65
|
+
case "sendMessage":
|
|
66
|
+
await svc.send(p);
|
|
67
|
+
return { ok: true };
|
|
68
|
+
case "saveDraft":
|
|
69
|
+
return svc.saveDraft(p.accountId, p.subject, p.bodyHtml, p.bodyText, p.to, p.cc, p.previousDraftUid, p.draftId);
|
|
70
|
+
case "deleteDraft":
|
|
71
|
+
await svc.deleteDraft(p.accountId, p.draftUid);
|
|
72
|
+
return { ok: true };
|
|
73
|
+
case "syncAll":
|
|
74
|
+
await svc.syncAll();
|
|
75
|
+
return { ok: true };
|
|
76
|
+
case "syncAccount":
|
|
77
|
+
await svc.syncAccount(p.accountId);
|
|
78
|
+
return { ok: true };
|
|
79
|
+
case "getSyncPending":
|
|
80
|
+
return svc.getSyncPending();
|
|
81
|
+
case "reauthenticate":
|
|
82
|
+
return { ok: await svc.reauthenticate(p.accountId) };
|
|
83
|
+
case "searchMessages":
|
|
84
|
+
return svc.search(p.query, p.page, p.pageSize, p.scope, p.accountId, p.folderId);
|
|
85
|
+
case "searchContacts":
|
|
86
|
+
return svc.searchContacts(p.query);
|
|
87
|
+
case "listContacts":
|
|
88
|
+
return svc.listContacts(p.query || "", p.page || 1, p.pageSize || 100);
|
|
89
|
+
case "upsertContact":
|
|
90
|
+
return svc.upsertContact(p.name || "", p.email);
|
|
91
|
+
case "deleteContact":
|
|
92
|
+
return svc.deleteContact(p.email);
|
|
93
|
+
case "addContact":
|
|
94
|
+
return svc.addContact(p.name || "", p.email);
|
|
95
|
+
case "getSettings":
|
|
96
|
+
return svc.getSettings();
|
|
97
|
+
case "saveSettingsData":
|
|
98
|
+
await svc.saveSettingsData(p);
|
|
99
|
+
return { ok: true };
|
|
100
|
+
case "allowRemoteContent":
|
|
101
|
+
await svc.allowRemoteContent(p.type, p.value);
|
|
102
|
+
return { ok: true };
|
|
103
|
+
case "flagSenderOrDomain":
|
|
104
|
+
return await svc.flagSenderOrDomain(p.type, p.value);
|
|
105
|
+
case "getPriorityLists":
|
|
106
|
+
return await svc.getPriorityLists();
|
|
107
|
+
case "setPrioritySender":
|
|
108
|
+
await svc.setPrioritySender(p.email, !!p.value, p.name);
|
|
109
|
+
return { ok: true };
|
|
110
|
+
case "setPriorityDomain":
|
|
111
|
+
await svc.setPriorityDomain(p.domain, !!p.value);
|
|
112
|
+
return { ok: true };
|
|
113
|
+
case "getVersion":
|
|
114
|
+
return { version: "1.0.0-android", theme: "system", storage: svc.getStorageInfo(), platform: "android" };
|
|
115
|
+
case "getAutocompleteSettings":
|
|
116
|
+
return svc.getAutocompleteSettings();
|
|
117
|
+
case "saveAutocompleteSettings":
|
|
118
|
+
await svc.saveAutocompleteSettings(p);
|
|
119
|
+
return { ok: true };
|
|
120
|
+
case "resetStore":
|
|
121
|
+
await svc.resetStore();
|
|
122
|
+
return { ok: true };
|
|
123
|
+
default:
|
|
124
|
+
throw new Error(`Unknown action: ${action}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexedDB-based message body storage for Android/browser.
|
|
3
|
+
* Mirrors FileMessageStore API from @bobfrankston/mailx-store.
|
|
4
|
+
* Stores RFC 2822 message bodies as blobs keyed by accountId/folderId/uid.
|
|
5
|
+
*/
|
|
6
|
+
export declare class WebMessageStore {
|
|
7
|
+
private dbPromise;
|
|
8
|
+
constructor();
|
|
9
|
+
putMessage(accountId: string, folderId: number, uid: number, raw: Uint8Array | ArrayBuffer): Promise<string>;
|
|
10
|
+
getMessage(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null>;
|
|
11
|
+
deleteMessage(accountId: string, folderId: number, uid: number): Promise<void>;
|
|
12
|
+
hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean>;
|
|
13
|
+
/** Clear all stored bodies — used for "Reset Store" */
|
|
14
|
+
clear(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=web-message-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-message-store.d.ts","sourceRoot":"","sources":["web-message-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH,qBAAa,eAAe;IACxB,OAAO,CAAC,SAAS,CAAuB;;IAMlC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAY5G,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAiBxF,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWpF,uDAAuD;IACjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS/B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexedDB-based message body storage for Android/browser.
|
|
3
|
+
* Mirrors FileMessageStore API from @bobfrankston/mailx-store.
|
|
4
|
+
* Stores RFC 2822 message bodies as blobs keyed by accountId/folderId/uid.
|
|
5
|
+
*/
|
|
6
|
+
const DB_NAME = "mailx-bodies";
|
|
7
|
+
const DB_VERSION = 1;
|
|
8
|
+
const STORE_NAME = "messages";
|
|
9
|
+
function openDb() {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
12
|
+
req.onupgradeneeded = () => {
|
|
13
|
+
const db = req.result;
|
|
14
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
15
|
+
db.createObjectStore(STORE_NAME);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
req.onsuccess = () => resolve(req.result);
|
|
19
|
+
req.onerror = () => reject(req.error);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function makeKey(accountId, folderId, uid) {
|
|
23
|
+
return `${accountId}/${folderId}/${uid}`;
|
|
24
|
+
}
|
|
25
|
+
export class WebMessageStore {
|
|
26
|
+
dbPromise;
|
|
27
|
+
constructor() {
|
|
28
|
+
this.dbPromise = openDb();
|
|
29
|
+
}
|
|
30
|
+
async putMessage(accountId, folderId, uid, raw) {
|
|
31
|
+
const db = await this.dbPromise;
|
|
32
|
+
const key = makeKey(accountId, folderId, uid);
|
|
33
|
+
const data = raw instanceof Uint8Array ? raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength) : raw;
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
36
|
+
tx.objectStore(STORE_NAME).put(data, key);
|
|
37
|
+
tx.oncomplete = () => resolve(key);
|
|
38
|
+
tx.onerror = () => reject(tx.error);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
async getMessage(accountId, folderId, uid) {
|
|
42
|
+
const db = await this.dbPromise;
|
|
43
|
+
const key = makeKey(accountId, folderId, uid);
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const tx = db.transaction(STORE_NAME, "readonly");
|
|
46
|
+
const req = tx.objectStore(STORE_NAME).get(key);
|
|
47
|
+
req.onsuccess = () => {
|
|
48
|
+
if (req.result) {
|
|
49
|
+
resolve(new Uint8Array(req.result));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
resolve(null);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
req.onerror = () => reject(req.error);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async deleteMessage(accountId, folderId, uid) {
|
|
59
|
+
const db = await this.dbPromise;
|
|
60
|
+
const key = makeKey(accountId, folderId, uid);
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
63
|
+
tx.objectStore(STORE_NAME).delete(key);
|
|
64
|
+
tx.oncomplete = () => resolve();
|
|
65
|
+
tx.onerror = () => reject(tx.error);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async hasMessage(accountId, folderId, uid) {
|
|
69
|
+
const db = await this.dbPromise;
|
|
70
|
+
const key = makeKey(accountId, folderId, uid);
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
const tx = db.transaction(STORE_NAME, "readonly");
|
|
73
|
+
const req = tx.objectStore(STORE_NAME).count(IDBKeyRange.only(key));
|
|
74
|
+
req.onsuccess = () => resolve(req.result > 0);
|
|
75
|
+
req.onerror = () => reject(req.error);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/** Clear all stored bodies — used for "Reset Store" */
|
|
79
|
+
async clear() {
|
|
80
|
+
const db = await this.dbPromise;
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
83
|
+
tx.objectStore(STORE_NAME).clear();
|
|
84
|
+
tx.oncomplete = () => resolve();
|
|
85
|
+
tx.onerror = () => reject(tx.error);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=web-message-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-message-store.js","sourceRoot":"","sources":["web-message-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexedDB-based message body storage for Android/browser.
|
|
3
|
+
* Mirrors FileMessageStore API from @bobfrankston/mailx-store.
|
|
4
|
+
* Stores RFC 2822 message bodies as blobs keyed by accountId/folderId/uid.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const DB_NAME = "mailx-bodies";
|
|
8
|
+
const DB_VERSION = 1;
|
|
9
|
+
const STORE_NAME = "messages";
|
|
10
|
+
|
|
11
|
+
function openDb(): Promise<IDBDatabase> {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
14
|
+
req.onupgradeneeded = () => {
|
|
15
|
+
const db = req.result;
|
|
16
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
17
|
+
db.createObjectStore(STORE_NAME);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
req.onsuccess = () => resolve(req.result);
|
|
21
|
+
req.onerror = () => reject(req.error);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function makeKey(accountId: string, folderId: number, uid: number): string {
|
|
26
|
+
return `${accountId}/${folderId}/${uid}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class WebMessageStore {
|
|
30
|
+
private dbPromise: Promise<IDBDatabase>;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
this.dbPromise = openDb();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async putMessage(accountId: string, folderId: number, uid: number, raw: Uint8Array | ArrayBuffer): Promise<string> {
|
|
37
|
+
const db = await this.dbPromise;
|
|
38
|
+
const key = makeKey(accountId, folderId, uid);
|
|
39
|
+
const data = raw instanceof Uint8Array ? raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength) : raw;
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
42
|
+
tx.objectStore(STORE_NAME).put(data, key);
|
|
43
|
+
tx.oncomplete = () => resolve(key);
|
|
44
|
+
tx.onerror = () => reject(tx.error);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async getMessage(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null> {
|
|
49
|
+
const db = await this.dbPromise;
|
|
50
|
+
const key = makeKey(accountId, folderId, uid);
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const tx = db.transaction(STORE_NAME, "readonly");
|
|
53
|
+
const req = tx.objectStore(STORE_NAME).get(key);
|
|
54
|
+
req.onsuccess = () => {
|
|
55
|
+
if (req.result) {
|
|
56
|
+
resolve(new Uint8Array(req.result as ArrayBuffer));
|
|
57
|
+
} else {
|
|
58
|
+
resolve(null);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
req.onerror = () => reject(req.error);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async deleteMessage(accountId: string, folderId: number, uid: number): Promise<void> {
|
|
66
|
+
const db = await this.dbPromise;
|
|
67
|
+
const key = makeKey(accountId, folderId, uid);
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
70
|
+
tx.objectStore(STORE_NAME).delete(key);
|
|
71
|
+
tx.oncomplete = () => resolve();
|
|
72
|
+
tx.onerror = () => reject(tx.error);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async hasMessage(accountId: string, folderId: number, uid: number): Promise<boolean> {
|
|
77
|
+
const db = await this.dbPromise;
|
|
78
|
+
const key = makeKey(accountId, folderId, uid);
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
const tx = db.transaction(STORE_NAME, "readonly");
|
|
81
|
+
const req = tx.objectStore(STORE_NAME).count(IDBKeyRange.only(key));
|
|
82
|
+
req.onsuccess = () => resolve(req.result > 0);
|
|
83
|
+
req.onerror = () => reject(req.error);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Clear all stored bodies — used for "Reset Store" */
|
|
88
|
+
async clear(): Promise<void> {
|
|
89
|
+
const db = await this.dbPromise;
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const tx = db.transaction(STORE_NAME, "readwrite");
|
|
92
|
+
tx.objectStore(STORE_NAME).clear();
|
|
93
|
+
tx.oncomplete = () => resolve();
|
|
94
|
+
tx.onerror = () => reject(tx.error);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
package/web-service.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web-compatible MailxService for Android/browser.
|
|
3
|
+
* Replaces @bobfrankston/mailx-service which depends on Node.js (fs, dns, mailparser).
|
|
4
|
+
*
|
|
5
|
+
* Key differences from desktop:
|
|
6
|
+
* - Uses WebMailxDB (wa-sqlite) instead of MailxDB (node:sqlite)
|
|
7
|
+
* - Uses WebMessageStore (IndexedDB) instead of FileMessageStore (filesystem)
|
|
8
|
+
* - Uses postal-mime or manual header parsing instead of mailparser's simpleParser
|
|
9
|
+
* - Settings via IndexedDB + GDrive API instead of filesystem
|
|
10
|
+
* - No dns.resolveMx — provider detection is static (Gmail/Outlook/Yahoo/iCloud)
|
|
11
|
+
*/
|
|
12
|
+
import type { WebMailxDB } from "./db.js";
|
|
13
|
+
import type { WebMessageStore } from "./web-message-store.js";
|
|
14
|
+
import type { Folder, AutocompleteSettings } from "@bobfrankston/mailx-types";
|
|
15
|
+
export interface WebSyncManager {
|
|
16
|
+
syncAll(): Promise<void>;
|
|
17
|
+
syncFolders(accountId: string): Promise<Folder[]>;
|
|
18
|
+
syncFolder(accountId: string, folderId: number): Promise<void>;
|
|
19
|
+
fetchMessageBody(accountId: string, folderId: number, uid: number): Promise<Uint8Array | null>;
|
|
20
|
+
updateFlagsLocal(accountId: string, uid: number, folderId: number, flags: string[]): Promise<void>;
|
|
21
|
+
trashMessage(accountId: string, folderId: number, uid: number): Promise<void>;
|
|
22
|
+
trashMessages(accountId: string, messages: {
|
|
23
|
+
uid: number;
|
|
24
|
+
folderId: number;
|
|
25
|
+
}[]): Promise<void>;
|
|
26
|
+
moveMessage(accountId: string, uid: number, folderId: number, targetFolderId: number): Promise<void>;
|
|
27
|
+
moveMessages(accountId: string, messages: {
|
|
28
|
+
uid: number;
|
|
29
|
+
folderId: number;
|
|
30
|
+
}[], targetFolderId: number): Promise<void>;
|
|
31
|
+
moveMessageCrossAccount(accountId: string, uid: number, folderId: number, targetAccountId: string, targetFolderId: number): Promise<void>;
|
|
32
|
+
undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void>;
|
|
33
|
+
queueOutgoingLocal(accountId: string, rawMessage: string): void | Promise<void>;
|
|
34
|
+
saveDraft(accountId: string, raw: string, previousDraftUid?: number, draftId?: string): Promise<number | null>;
|
|
35
|
+
deleteDraft(accountId: string, draftUid: number): Promise<void>;
|
|
36
|
+
reauthenticate(accountId: string): Promise<boolean>;
|
|
37
|
+
searchOnServer(accountId: string, folderPath: string, criteria: any): Promise<number[]>;
|
|
38
|
+
syncAllContacts(): Promise<void>;
|
|
39
|
+
addAccount(account: any): Promise<void>;
|
|
40
|
+
on(event: string, handler: (...args: any[]) => void): void;
|
|
41
|
+
emit(event: string, ...args: any[]): void;
|
|
42
|
+
}
|
|
43
|
+
export declare class WebMailxService {
|
|
44
|
+
private db;
|
|
45
|
+
private bodyStore;
|
|
46
|
+
private syncManager;
|
|
47
|
+
constructor(db: WebMailxDB, bodyStore: WebMessageStore, syncManager: WebSyncManager);
|
|
48
|
+
getAccounts(): Promise<any[]>;
|
|
49
|
+
getFolders(accountId: string): Folder[];
|
|
50
|
+
getUnifiedInbox(page?: number, pageSize?: number): any;
|
|
51
|
+
getMessages(accountId: string, folderId: number, page?: number, pageSize?: number, sort?: string, sortDir?: string, search?: string): any;
|
|
52
|
+
getMessage(accountId: string, uid: number, allowRemote?: boolean, folderId?: number): Promise<any>;
|
|
53
|
+
/** Flag (or unflag) a sender / domain. Mirrors the desktop service so
|
|
54
|
+
* the viewer's right-click "Flag sender" / "Flag domain" buttons work
|
|
55
|
+
* on phone — was a no-op on Android before. Toggles membership in
|
|
56
|
+
* flaggedSenders / flaggedDomains in allowlist.jsonc, which syncs
|
|
57
|
+
* back to the cloud copy. */
|
|
58
|
+
flagSenderOrDomain(type: "sender" | "domain", value: string): Promise<{
|
|
59
|
+
flagged: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
updateFlags(accountId: string, uid: number, flags: string[]): Promise<void>;
|
|
62
|
+
allowRemoteContent(type: "sender" | "domain" | "recipient", value: string): Promise<void>;
|
|
63
|
+
search(q: string, page?: number, pageSize?: number, scope?: string, accountId?: string, folderId?: number): Promise<any>;
|
|
64
|
+
getSyncPending(): {
|
|
65
|
+
pending: number;
|
|
66
|
+
};
|
|
67
|
+
syncAll(): Promise<void>;
|
|
68
|
+
syncAccount(accountId: string): Promise<void>;
|
|
69
|
+
reauthenticate(accountId: string): Promise<boolean>;
|
|
70
|
+
send(msg: any): Promise<void>;
|
|
71
|
+
deleteMessage(accountId: string, uid: number): Promise<void>;
|
|
72
|
+
deleteMessages(accountId: string, uids: number[]): Promise<void>;
|
|
73
|
+
moveMessage(accountId: string, uid: number, targetFolderId: number, targetAccountId?: string): Promise<void>;
|
|
74
|
+
moveMessages(accountId: string, uids: number[], targetFolderId: number): Promise<void>;
|
|
75
|
+
undeleteMessage(accountId: string, uid: number, folderId: number): Promise<void>;
|
|
76
|
+
saveDraft(accountId: string, subject: string, bodyHtml: string, bodyText: string, to?: string, cc?: string, previousDraftUid?: number, draftId?: string): Promise<{
|
|
77
|
+
uid: number | null;
|
|
78
|
+
draftId: string;
|
|
79
|
+
}>;
|
|
80
|
+
deleteDraft(accountId: string, draftUid: number): Promise<void>;
|
|
81
|
+
searchContacts(query: string): any[];
|
|
82
|
+
/** Address-book listing — paginated, filterable. Mirrors mailx-service's
|
|
83
|
+
* signature so the same client-side address-book modal works on Android
|
|
84
|
+
* without an "ipc(...).listContacts is not a function" crash. */
|
|
85
|
+
listContacts(query: string, page?: number, pageSize?: number): {
|
|
86
|
+
items: any[];
|
|
87
|
+
total: number;
|
|
88
|
+
page: number;
|
|
89
|
+
pageSize: number;
|
|
90
|
+
};
|
|
91
|
+
/** Manual upsert from the address-book UI. The desktop path queues a
|
|
92
|
+
* Google People sync; Android relies on the desktop pushing changes
|
|
93
|
+
* back, so this is local-only for now. */
|
|
94
|
+
upsertContact(name: string, email: string): {
|
|
95
|
+
ok: true;
|
|
96
|
+
};
|
|
97
|
+
deleteContact(email: string): {
|
|
98
|
+
ok: true;
|
|
99
|
+
};
|
|
100
|
+
addContact(name: string, email: string): boolean;
|
|
101
|
+
/** Q49 heuristic mirror: true if the user has ever sent a message to
|
|
102
|
+
* `recipientEmail` that had a non-empty Cc field. Compose uses this to
|
|
103
|
+
* decide whether to auto-expand the Cc row on reply. */
|
|
104
|
+
hasCcHistoryTo(recipientEmail: string): boolean;
|
|
105
|
+
getSettings(): Promise<any>;
|
|
106
|
+
saveSettingsData(settings: any): Promise<void>;
|
|
107
|
+
getStorageInfo(): {
|
|
108
|
+
provider: string;
|
|
109
|
+
mode: string;
|
|
110
|
+
folderId?: string;
|
|
111
|
+
folderName?: string;
|
|
112
|
+
folderPath?: string;
|
|
113
|
+
folderOwner?: string;
|
|
114
|
+
};
|
|
115
|
+
markFolderRead(folderId: number): void;
|
|
116
|
+
getAutocompleteSettings(): Promise<AutocompleteSettings>;
|
|
117
|
+
saveAutocompleteSettings(settings: AutocompleteSettings): Promise<void>;
|
|
118
|
+
autocomplete(_req: any): Promise<{
|
|
119
|
+
suggestion: string;
|
|
120
|
+
}>;
|
|
121
|
+
resetStore(): Promise<void>;
|
|
122
|
+
readJsoncFile(name: string): Promise<string | null>;
|
|
123
|
+
writeJsoncFile(name: string, content: string): Promise<void>;
|
|
124
|
+
formatJsonc(content: string): Promise<string>;
|
|
125
|
+
readConfigHelp(_name: string): Promise<string>;
|
|
126
|
+
/** Compute and return the priority sender / domain index from the
|
|
127
|
+
* current contacts.jsonc. Reads from cloud (or local cache) every
|
|
128
|
+
* call — small file, simpler than maintaining a long-lived cache. */
|
|
129
|
+
getPriorityLists(): Promise<{
|
|
130
|
+
senders: string[];
|
|
131
|
+
domains: string[];
|
|
132
|
+
}>;
|
|
133
|
+
setPrioritySender(email: string, value: boolean, name?: string): Promise<void>;
|
|
134
|
+
setPriorityDomain(domain: string, value: boolean): Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=web-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-service.d.ts","sourceRoot":"","sources":["web-service.ts"],"names":[],"mappings":"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"}
|