@bobfrankston/iflow-direct 0.1.13 → 0.1.15

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.
@@ -1,30 +1,7 @@
1
1
  /**
2
- * Bridge transport for IMAP uses msgapi.tcp from the native shell.
3
- * Works in any msgapi host: msga (MAUI), msger (Rust/wry), msgview (Electron).
4
- *
5
- * The native shell provides:
6
- * msgapi.tcp.connect(host, port, tls) → streamId
7
- * msgapi.tcp.write(streamId, data)
8
- * msgapi.tcp.onData(streamId, callback)
9
- * msgapi.tcp.upgradeTLS(streamId, servername)
10
- * msgapi.tcp.close(streamId)
11
- *
12
- * TLS is handled natively — JS never sees raw TLS handshake.
2
+ * Back-compat re-export. `BridgeTransport` was renamed to `BridgeTcpTransport`
3
+ * and moved to @bobfrankston/tcp-transport. New code should import that
4
+ * directly. This shim keeps existing imports working.
13
5
  */
14
- import type { ImapTransport } from "./transport.js";
15
- export declare class BridgeTransport implements ImapTransport {
16
- private streamId;
17
- private dataHandler;
18
- private closeHandler;
19
- private errorHandler;
20
- private _connected;
21
- get connected(): boolean;
22
- connect(host: string, port: number, tls: boolean, _servername?: string): Promise<void>;
23
- upgradeTLS(servername?: string): Promise<void>;
24
- write(data: string | Uint8Array): Promise<void>;
25
- onData(handler: (data: string) => void): void;
26
- onClose(handler: (hadError: boolean) => void): void;
27
- onError(handler: (err: Error) => void): void;
28
- close(): void;
29
- }
6
+ export { BridgeTcpTransport as BridgeTransport } from "@bobfrankston/tcp-transport";
30
7
  //# sourceMappingURL=bridge-transport.d.ts.map
@@ -1,60 +1,7 @@
1
1
  /**
2
- * Bridge transport for IMAP uses msgapi.tcp from the native shell.
3
- * Works in any msgapi host: msga (MAUI), msger (Rust/wry), msgview (Electron).
4
- *
5
- * The native shell provides:
6
- * msgapi.tcp.connect(host, port, tls) → streamId
7
- * msgapi.tcp.write(streamId, data)
8
- * msgapi.tcp.onData(streamId, callback)
9
- * msgapi.tcp.upgradeTLS(streamId, servername)
10
- * msgapi.tcp.close(streamId)
11
- *
12
- * TLS is handled natively — JS never sees raw TLS handshake.
2
+ * Back-compat re-export. `BridgeTransport` was renamed to `BridgeTcpTransport`
3
+ * and moved to @bobfrankston/tcp-transport. New code should import that
4
+ * directly. This shim keeps existing imports working.
13
5
  */
14
- export class BridgeTransport {
15
- streamId = null;
16
- dataHandler = null;
17
- closeHandler = null;
18
- errorHandler = null;
19
- _connected = false;
20
- get connected() { return this._connected; }
21
- async connect(host, port, tls, _servername) {
22
- this.streamId = await msgapi.tcp.connect(host, port, tls);
23
- this._connected = true;
24
- msgapi.tcp.onData(this.streamId, (data) => {
25
- if (this.dataHandler)
26
- this.dataHandler(data);
27
- });
28
- msgapi.tcp.onClose(this.streamId, (hadError) => {
29
- this._connected = false;
30
- if (this.closeHandler)
31
- this.closeHandler(hadError);
32
- });
33
- msgapi.tcp.onError(this.streamId, (message) => {
34
- if (this.errorHandler)
35
- this.errorHandler(new Error(message));
36
- });
37
- }
38
- async upgradeTLS(servername) {
39
- if (this.streamId == null)
40
- throw new Error("Not connected");
41
- await msgapi.tcp.upgradeTLS(this.streamId, servername || "");
42
- }
43
- async write(data) {
44
- if (this.streamId == null)
45
- throw new Error("Not connected");
46
- const str = typeof data === "string" ? data : new TextDecoder().decode(data);
47
- await msgapi.tcp.write(this.streamId, str);
48
- }
49
- onData(handler) { this.dataHandler = handler; }
50
- onClose(handler) { this.closeHandler = handler; }
51
- onError(handler) { this.errorHandler = handler; }
52
- close() {
53
- this._connected = false;
54
- if (this.streamId != null) {
55
- msgapi.tcp.close(this.streamId);
56
- this.streamId = null;
57
- }
58
- }
59
- }
6
+ export { BridgeTcpTransport as BridgeTransport } from "@bobfrankston/tcp-transport";
60
7
  //# sourceMappingURL=bridge-transport.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * FetchedMessage — NativeFetchedMessage plus parsed-header state and convenience getters.
3
+ *
4
+ * Inherits the NativeFetchedMessage shape (via `implements`) so a FetchedMessage
5
+ * is-a NativeFetchedMessage: it can be passed anywhere the native interface is
6
+ * expected. Callers that want the raw shape treat it as NativeFetchedMessage;
7
+ * callers that want extras read `.ymd`, `.listUnsubscribe`, etc. directly.
8
+ */
9
+ import type { NativeFetchedMessage } from "./imap-native.js";
10
+ import type { AddressData } from "./imap-protocol.js";
11
+ /** Case-insensitive multi-value header map (one key may repeat). */
12
+ declare class HeaderMap {
13
+ private items;
14
+ add(key: string, value: string): void;
15
+ get(key: string): string[] | undefined;
16
+ }
17
+ export declare class FetchedMessage implements NativeFetchedMessage {
18
+ seq: number;
19
+ uid: number;
20
+ flags: Set<string>;
21
+ date: Date | null;
22
+ subject: string;
23
+ messageId: string;
24
+ from: AddressData[];
25
+ to: AddressData[];
26
+ cc: AddressData[];
27
+ bcc: AddressData[];
28
+ sender: AddressData[];
29
+ replyTo: AddressData[];
30
+ inReplyTo: string;
31
+ size: number;
32
+ source: string;
33
+ headers: string;
34
+ seen: boolean;
35
+ flagged: boolean;
36
+ answered: boolean;
37
+ draft: boolean;
38
+ parsedHeader: string[][];
39
+ headerSet: HeaderMap;
40
+ constructor(init: NativeFetchedMessage);
41
+ get unread(): boolean;
42
+ get deleted(): boolean;
43
+ get hasFlag(): boolean;
44
+ get ymd(): string | undefined;
45
+ /** Self-typed as a keyable record for dynamic address-field access by screening rules. */
46
+ get tcsb(): Record<string, AddressData[]>;
47
+ get listUnsubscribe(): string | undefined;
48
+ get xpriority(): string | undefined;
49
+ get importance(): string | undefined;
50
+ get deliveredTo(): string | undefined;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=fetched-message.d.ts.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * FetchedMessage — NativeFetchedMessage plus parsed-header state and convenience getters.
3
+ *
4
+ * Inherits the NativeFetchedMessage shape (via `implements`) so a FetchedMessage
5
+ * is-a NativeFetchedMessage: it can be passed anywhere the native interface is
6
+ * expected. Callers that want the raw shape treat it as NativeFetchedMessage;
7
+ * callers that want extras read `.ymd`, `.listUnsubscribe`, etc. directly.
8
+ */
9
+ /** Case-insensitive multi-value header map (one key may repeat). */
10
+ class HeaderMap {
11
+ items = {};
12
+ add(key, value) {
13
+ const k = key.toLowerCase();
14
+ (this.items[k] ||= []).push(value);
15
+ }
16
+ get(key) {
17
+ return this.items[key.toLowerCase()];
18
+ }
19
+ }
20
+ export class FetchedMessage {
21
+ // Native fields — populated by Object.assign in the constructor.
22
+ // `implements NativeFetchedMessage` forces this list to stay in sync.
23
+ seq;
24
+ uid;
25
+ flags;
26
+ date;
27
+ subject;
28
+ messageId;
29
+ from;
30
+ to;
31
+ cc;
32
+ bcc;
33
+ sender;
34
+ replyTo;
35
+ inReplyTo;
36
+ size;
37
+ source;
38
+ headers;
39
+ seen;
40
+ flagged;
41
+ answered;
42
+ draft;
43
+ // Parsed-header state
44
+ parsedHeader;
45
+ headerSet;
46
+ constructor(init) {
47
+ Object.assign(this, init);
48
+ // RFC 5322 unfold: a line starting with whitespace continues the prior one.
49
+ const unfolded = (init.headers || "").replace(/\r\n(\s)/g, "$1");
50
+ this.parsedHeader = unfolded
51
+ .split(/\r?\n/)
52
+ .filter(line => line.trim() !== "")
53
+ .map(line => {
54
+ const i = line.indexOf(":");
55
+ return i < 0 ? [line, ""] : [line.slice(0, i), line.slice(i + 1).trim()];
56
+ });
57
+ this.headerSet = new HeaderMap();
58
+ for (const [k, v] of this.parsedHeader)
59
+ this.headerSet.add(k, v);
60
+ }
61
+ // Flag convenience
62
+ get unread() { return !this.seen; }
63
+ get deleted() { return this.flags.has("\\Deleted"); }
64
+ get hasFlag() { return this.flags.size > 0; }
65
+ // Display
66
+ get ymd() { return this.date?.toLocaleDateString("se"); }
67
+ /** Self-typed as a keyable record for dynamic address-field access by screening rules. */
68
+ get tcsb() {
69
+ return this;
70
+ }
71
+ // Parsed-header lookups
72
+ get listUnsubscribe() { return this.headerSet.get("List-Unsubscribe")?.[0]; }
73
+ get xpriority() { return this.headerSet.get("X-Priority")?.[0]; }
74
+ get importance() { return this.headerSet.get("Importance")?.[0]; }
75
+ get deliveredTo() { return this.headerSet.get("Delivered-To")?.[0]; }
76
+ }
77
+ //# sourceMappingURL=fetched-message.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Folder tree builder — converts a flat NativeFolder[] into a nested tree.
3
+ * Equivalent to imapflow's listTree(), but pure JS and transport-agnostic.
4
+ * Parents are derived from path + delimiter (NativeFolder has no pre-parsed parent[]).
5
+ */
6
+ import type { NativeFolder } from "./imap-native.js";
7
+ export interface FolderTreeNode {
8
+ /** Root sentinel — only true on the returned top-level container */
9
+ root?: boolean;
10
+ /** Full mailbox path (empty string for root) */
11
+ path: string;
12
+ /** Leaf name (last segment of path) */
13
+ name: string;
14
+ /** Path delimiter from the server */
15
+ delimiter: string;
16
+ /** IMAP flags (e.g. "\\HasChildren", "\\Noselect", "\\Inbox") */
17
+ flags: string[];
18
+ /** Detected special-use tag (sent/trash/drafts/spam/archive/inbox), if known */
19
+ specialUse?: string;
20
+ /** True if the folder itself cannot be selected (e.g. "\\Noselect" flag) */
21
+ disabled?: boolean;
22
+ /** Child folders */
23
+ folders: FolderTreeNode[];
24
+ }
25
+ /** Build a nested tree from a flat folder list using path + delimiter. */
26
+ export declare function buildFolderTree(folders: NativeFolder[]): FolderTreeNode;
27
+ //# sourceMappingURL=folder-tree.d.ts.map
package/folder-tree.js ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Folder tree builder — converts a flat NativeFolder[] into a nested tree.
3
+ * Equivalent to imapflow's listTree(), but pure JS and transport-agnostic.
4
+ * Parents are derived from path + delimiter (NativeFolder has no pre-parsed parent[]).
5
+ */
6
+ /** Build a nested tree from a flat folder list using path + delimiter. */
7
+ export function buildFolderTree(folders) {
8
+ const delimiter = folders[0]?.delimiter || ".";
9
+ const root = { root: true, path: "", name: "", delimiter, flags: [], folders: [] };
10
+ const byPath = new Map();
11
+ byPath.set("", root);
12
+ // Sort by path so parents are created before children
13
+ const sorted = [...folders].sort((a, b) => a.path.localeCompare(b.path));
14
+ for (const f of sorted) {
15
+ const delim = f.delimiter || delimiter;
16
+ const parts = f.path.split(delim);
17
+ const name = parts[parts.length - 1];
18
+ const node = {
19
+ path: f.path,
20
+ name,
21
+ delimiter: delim,
22
+ flags: f.flags,
23
+ folders: [],
24
+ };
25
+ if (f.flags.some(fl => fl.toLowerCase() === "\\noselect"))
26
+ node.disabled = true;
27
+ // Find or create parent chain (handles gaps where an intermediate LIST entry is missing)
28
+ let parentPath = "";
29
+ let parent = root;
30
+ for (let i = 0; i < parts.length - 1; i++) {
31
+ parentPath = parentPath ? parentPath + delim + parts[i] : parts[i];
32
+ let p = byPath.get(parentPath);
33
+ if (!p) {
34
+ p = { path: parentPath, name: parts[i], delimiter: delim, flags: [], folders: [], disabled: true };
35
+ byPath.set(parentPath, p);
36
+ parent.folders.push(p);
37
+ }
38
+ parent = p;
39
+ }
40
+ const existing = byPath.get(f.path);
41
+ if (existing) {
42
+ // Fill in a placeholder that was created for a descendant
43
+ existing.flags = f.flags;
44
+ existing.name = name;
45
+ existing.delimiter = delim;
46
+ delete existing.disabled;
47
+ if (f.flags.some(fl => fl.toLowerCase() === "\\noselect"))
48
+ existing.disabled = true;
49
+ }
50
+ else {
51
+ byPath.set(f.path, node);
52
+ parent.folders.push(node);
53
+ }
54
+ }
55
+ return root;
56
+ }
57
+ //# sourceMappingURL=folder-tree.js.map
package/imap-compat.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Each method opens the mailbox, does the operation, and returns. No persistent state.
5
5
  */
6
6
  import { type NativeFolder } from "./imap-native.js";
7
+ import { FetchedMessage } from "./fetched-message.js";
7
8
  import type { ImapClientConfig } from "./types.js";
8
9
  import type { TransportFactory } from "./transport.js";
9
10
  /** Special folder detection result */
@@ -36,15 +37,15 @@ export declare class CompatImapClient {
36
37
  /** Fetch messages since a UID in a mailbox */
37
38
  fetchMessagesSinceUid(mailbox: string, sinceUid: number, options?: {
38
39
  source?: boolean;
39
- }): Promise<any[]>;
40
+ }): Promise<FetchedMessage[]>;
40
41
  /** Fetch messages by date range. Optional onChunk callback for incremental processing. */
41
42
  fetchMessageByDate(mailbox: string, start: Date, end?: Date, options?: {
42
43
  source?: boolean;
43
- }, onChunk?: (msgs: any[]) => void): Promise<any[]>;
44
+ }, onChunk?: (msgs: FetchedMessage[]) => void): Promise<FetchedMessage[]>;
44
45
  /** Fetch a single message by UID */
45
46
  fetchMessageByUid(mailbox: string, uid: number, options?: {
46
47
  source?: boolean;
47
- }): Promise<any | null>;
48
+ }): Promise<FetchedMessage | null>;
48
49
  /** Get message count via STATUS (does not require SELECT) */
49
50
  getMessagesCount(mailbox: string): Promise<number>;
50
51
  /** Get all UIDs in a mailbox */
@@ -59,10 +60,10 @@ export declare class CompatImapClient {
59
60
  * used by the puller. */
60
61
  fetchMessages(mailbox: string, uidRange: string, options?: {
61
62
  source?: boolean;
62
- }): Promise<any[]>;
63
+ }): Promise<FetchedMessage[]>;
63
64
  fetchMessages(mailbox: string, end: number, count: number, options?: {
64
65
  source?: boolean;
65
- }): Promise<any[]>;
66
+ }): Promise<FetchedMessage[]>;
66
67
  /** Search messages in a mailbox */
67
68
  searchMessages(mailbox: string, criteria: any): Promise<number[]>;
68
69
  /** Search by header value — returns matching UIDs */
package/imap-compat.js CHANGED
@@ -4,44 +4,7 @@
4
4
  * Each method opens the mailbox, does the operation, and returns. No persistent state.
5
5
  */
6
6
  import { NativeImapClient } from "./imap-native.js";
7
- /** Convert NativeFetchedMessage to the old FetchedMessage shape used by mailx-imap */
8
- function toCompatMessage(msg) {
9
- return {
10
- uid: msg.uid,
11
- seq: msg.seq,
12
- flags: msg.flags,
13
- seen: msg.seen,
14
- flagged: msg.flagged,
15
- answered: msg.answered,
16
- draft: msg.draft,
17
- date: msg.date,
18
- subject: msg.subject,
19
- messageId: msg.messageId,
20
- from: msg.from,
21
- to: msg.to,
22
- cc: msg.cc,
23
- bcc: msg.bcc,
24
- sender: msg.sender,
25
- replyTo: msg.replyTo,
26
- inReplyTo: msg.inReplyTo,
27
- size: msg.size,
28
- source: msg.source,
29
- headers: msg.headers,
30
- // Compatibility: old FetchedMessage had envelope sub-object, but mailx-imap accesses directly
31
- envelope: {
32
- date: msg.date,
33
- subject: msg.subject,
34
- messageId: msg.messageId,
35
- from: msg.from,
36
- to: msg.to,
37
- cc: msg.cc,
38
- bcc: msg.bcc,
39
- sender: msg.sender,
40
- replyTo: msg.replyTo,
41
- inReplyTo: msg.inReplyTo,
42
- }
43
- };
44
- }
7
+ import { FetchedMessage } from "./fetched-message.js";
45
8
  /**
46
9
  * Compatibility IMAP client — wraps NativeImapClient with the old ImapClient API.
47
10
  * Each method creates its own select/operation/close cycle.
@@ -128,16 +91,16 @@ export class CompatImapClient {
128
91
  await this.native.select(mailbox);
129
92
  const msgs = await this.native.fetchSinceUid(sinceUid, options);
130
93
  await this.native.closeMailbox();
131
- return msgs.map(toCompatMessage);
94
+ return msgs.map(m => new FetchedMessage(m));
132
95
  }
133
96
  /** Fetch messages by date range. Optional onChunk callback for incremental processing. */
134
97
  async fetchMessageByDate(mailbox, start, end, options, onChunk) {
135
98
  await this.ensureConnected();
136
99
  await this.native.select(mailbox);
137
- const chunkCb = onChunk ? (raw) => onChunk(raw.map(toCompatMessage)) : undefined;
100
+ const chunkCb = onChunk ? (raw) => onChunk(raw.map(m => new FetchedMessage(m))) : undefined;
138
101
  const msgs = await this.native.fetchByDate(start, end, options, chunkCb);
139
102
  await this.native.closeMailbox();
140
- return msgs.map(toCompatMessage);
103
+ return msgs.map(m => new FetchedMessage(m));
141
104
  }
142
105
  /** Fetch a single message by UID */
143
106
  async fetchMessageByUid(mailbox, uid, options) {
@@ -145,7 +108,7 @@ export class CompatImapClient {
145
108
  await this.native.select(mailbox);
146
109
  const msg = await this.native.fetchMessage(uid, options);
147
110
  await this.native.closeMailbox();
148
- return msg ? toCompatMessage(msg) : null;
111
+ return msg ? new FetchedMessage(msg) : null;
149
112
  }
150
113
  /** Get message count via STATUS (does not require SELECT) */
151
114
  async getMessagesCount(mailbox) {
@@ -180,7 +143,7 @@ export class CompatImapClient {
180
143
  await this.native.select(mailbox);
181
144
  const msgs = await this.native.fetchMessages(range, options);
182
145
  await this.native.closeMailbox();
183
- return msgs.map(toCompatMessage);
146
+ return msgs.map(m => new FetchedMessage(m));
184
147
  }
185
148
  /** Search messages in a mailbox */
186
149
  async searchMessages(mailbox, criteria) {
package/index.d.ts CHANGED
@@ -14,5 +14,8 @@ export { NativeImapClient } from "./imap-native.js";
14
14
  export type { NativeFetchedMessage, NativeFolder, MailboxInfo } from "./imap-native.js";
15
15
  export { CompatImapClient } from "./imap-compat.js";
16
16
  export type { SpecialFolders } from "./imap-compat.js";
17
+ export { FetchedMessage } from "./fetched-message.js";
18
+ export { buildFolderTree } from "./folder-tree.js";
19
+ export type { FolderTreeNode } from "./folder-tree.js";
17
20
  export { isGmailUser, isGmailServer, createGmailConfig, createAutoImapConfig, type GmailOAuthConfig, } from "./gmail.js";
18
21
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -13,6 +13,10 @@ export * as proto from "./imap-protocol.js";
13
13
  export { NativeImapClient } from "./imap-native.js";
14
14
  // Compatibility wrapper (old ImapClient API shape)
15
15
  export { CompatImapClient } from "./imap-compat.js";
16
+ // Rich message wrapper (ported from @bobfrankston/iflow — parses headers, exposes ymd/tcsb/etc.)
17
+ export { FetchedMessage } from "./fetched-message.js";
18
+ // Folder tree builder (equivalent to imapflow.listTree, pure JS)
19
+ export { buildFolderTree } from "./folder-tree.js";
16
20
  // Gmail OAuth support (Node-free — caller provides tokenProvider)
17
21
  export { isGmailUser, isGmailServer, createGmailConfig, createAutoImapConfig, } from "./gmail.js";
18
22
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/iflow-direct",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Direct IMAP client — transport-agnostic, no Node.js dependencies, browser-ready",
5
5
  "main": "index.js",
6
6
  "types": "index.ts",
@@ -18,6 +18,9 @@
18
18
  ],
19
19
  "author": "Bob Frankston",
20
20
  "license": "ISC",
21
+ "dependencies": {
22
+ "@bobfrankston/tcp-transport": "^0.1.0"
23
+ },
21
24
  "exports": {
22
25
  ".": {
23
26
  "types": "./index.ts",
@@ -38,5 +41,13 @@
38
41
  "repository": {
39
42
  "type": "git",
40
43
  "url": "https://github.com/BobFrankston/iflow-direct.git"
44
+ },
45
+ ".dependencies": {
46
+ "@bobfrankston/tcp-transport": "file:../tcp-transport"
47
+ },
48
+ ".transformedSnapshot": {
49
+ "dependencies": {
50
+ "@bobfrankston/tcp-transport": "^0.1.0"
51
+ }
41
52
  }
42
53
  }
package/transport.d.ts CHANGED
@@ -1,25 +1,11 @@
1
1
  /**
2
- * Abstract transport interface for IMAP connections.
3
- * Implementations: NodeTransport (desktop), BridgeTransport (Android/WebView)
2
+ * Back-compat re-export. The TCP transport interface lives in
3
+ * @bobfrankston/tcp-transport it's protocol-agnostic, used by SMTP, IMAP,
4
+ * and any other line-oriented TCP code.
5
+ *
6
+ * `ImapTransport` is kept as an alias for `TcpTransport` so existing callers
7
+ * continue to compile. New code should import `TcpTransport` directly from
8
+ * @bobfrankston/tcp-transport.
4
9
  */
5
- export interface ImapTransport {
6
- /** Connect to host:port. If tls=true, connect with TLS directly (port 993). */
7
- connect(host: string, port: number, tls: boolean, servername?: string): Promise<void>;
8
- /** Upgrade an existing plaintext connection to TLS (STARTTLS). */
9
- upgradeTLS(servername?: string): Promise<void>;
10
- /** Write data to the connection. */
11
- write(data: string | Uint8Array): Promise<void>;
12
- /** Register a handler for incoming data. */
13
- onData(handler: (data: string) => void): void;
14
- /** Register a handler for connection close. */
15
- onClose(handler: (hadError: boolean) => void): void;
16
- /** Register a handler for errors. */
17
- onError(handler: (err: Error) => void): void;
18
- /** Close the connection. */
19
- close(): void;
20
- /** Whether the connection is active. */
21
- readonly connected: boolean;
22
- }
23
- /** Factory function type for creating transports */
24
- export type TransportFactory = () => ImapTransport;
10
+ export type { TcpTransport as ImapTransport, TransportFactory } from "@bobfrankston/tcp-transport";
25
11
  //# sourceMappingURL=transport.d.ts.map
package/transport.js CHANGED
@@ -1,6 +1,11 @@
1
1
  /**
2
- * Abstract transport interface for IMAP connections.
3
- * Implementations: NodeTransport (desktop), BridgeTransport (Android/WebView)
2
+ * Back-compat re-export. The TCP transport interface lives in
3
+ * @bobfrankston/tcp-transport it's protocol-agnostic, used by SMTP, IMAP,
4
+ * and any other line-oriented TCP code.
5
+ *
6
+ * `ImapTransport` is kept as an alias for `TcpTransport` so existing callers
7
+ * continue to compile. New code should import `TcpTransport` directly from
8
+ * @bobfrankston/tcp-transport.
4
9
  */
5
10
  export {};
6
11
  //# sourceMappingURL=transport.js.map