@composy/chat-core 0.0.1 → 0.0.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.
Files changed (168) hide show
  1. package/README.md +187 -123
  2. package/dist/index.js +2018 -1035
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.min.js +1370 -1644
  5. package/dist/index.min.js.map +1 -0
  6. package/es/.dts-output-manifest.json +1 -0
  7. package/es/.dts.tsbuildinfo +1 -0
  8. package/es/constants/dom.d.ts +3 -19
  9. package/es/constants/dom.js +4 -4
  10. package/es/constants/dom.js.map +1 -1
  11. package/es/core/chat-manager.d.ts +33 -22
  12. package/es/core/chat-manager.js +174 -50
  13. package/es/core/chat-manager.js.map +1 -1
  14. package/es/core/event-emitter.d.ts +0 -1
  15. package/es/core/event-emitter.js +14 -7
  16. package/es/core/event-emitter.js.map +1 -1
  17. package/es/core/mention-engine.d.ts +1 -2
  18. package/es/core/mention-engine.js +9 -9
  19. package/es/core/mention-engine.js.map +1 -1
  20. package/es/core/message-schema.d.ts +19 -0
  21. package/es/core/message-schema.js +197 -0
  22. package/es/core/message-schema.js.map +1 -0
  23. package/es/core/outbox.d.ts +63 -0
  24. package/es/core/outbox.js +160 -0
  25. package/es/core/outbox.js.map +1 -0
  26. package/es/core/transport.d.ts +79 -0
  27. package/es/core/transport.js +102 -0
  28. package/es/core/transport.js.map +1 -0
  29. package/es/index.d.ts +12 -7
  30. package/es/index.js +167 -36
  31. package/es/index.js.map +1 -1
  32. package/es/renderer/dom-renderer.d.ts +16 -4
  33. package/es/renderer/dom-renderer.js +316 -61
  34. package/es/renderer/dom-renderer.js.map +1 -1
  35. package/es/renderer/style-manager.d.ts +14 -38
  36. package/es/renderer/style-manager.js +92 -63
  37. package/es/renderer/style-manager.js.map +1 -1
  38. package/es/theme/theme-manager.d.ts +4 -3
  39. package/es/theme/theme-manager.js +19 -9
  40. package/es/theme/theme-manager.js.map +1 -1
  41. package/es/theme/tokens.d.ts +0 -1
  42. package/es/theme/tokens.js +92 -92
  43. package/es/theme/tokens.js.map +1 -1
  44. package/es/types/index.d.ts +104 -24
  45. package/es/types/index.js +8 -3
  46. package/es/types/index.js.map +1 -0
  47. package/esm/constants/dom.d.ts +3 -19
  48. package/esm/constants/dom.js +4 -4
  49. package/esm/constants/dom.js.map +1 -1
  50. package/esm/core/chat-manager.d.ts +33 -22
  51. package/esm/core/chat-manager.js +174 -50
  52. package/esm/core/chat-manager.js.map +1 -1
  53. package/esm/core/event-emitter.d.ts +0 -1
  54. package/esm/core/event-emitter.js +14 -7
  55. package/esm/core/event-emitter.js.map +1 -1
  56. package/esm/core/mention-engine.d.ts +1 -2
  57. package/esm/core/mention-engine.js +9 -9
  58. package/esm/core/mention-engine.js.map +1 -1
  59. package/esm/core/message-schema.d.ts +19 -0
  60. package/esm/core/message-schema.js +197 -0
  61. package/esm/core/message-schema.js.map +1 -0
  62. package/esm/core/outbox.d.ts +63 -0
  63. package/esm/core/outbox.js +160 -0
  64. package/esm/core/outbox.js.map +1 -0
  65. package/esm/core/transport.d.ts +79 -0
  66. package/esm/core/transport.js +102 -0
  67. package/esm/core/transport.js.map +1 -0
  68. package/esm/index.d.ts +12 -7
  69. package/esm/index.js +169 -38
  70. package/esm/index.js.map +1 -1
  71. package/esm/renderer/dom-renderer.d.ts +16 -4
  72. package/esm/renderer/dom-renderer.js +316 -61
  73. package/esm/renderer/dom-renderer.js.map +1 -1
  74. package/esm/renderer/style-manager.d.ts +14 -38
  75. package/esm/renderer/style-manager.js +92 -63
  76. package/esm/renderer/style-manager.js.map +1 -1
  77. package/esm/theme/theme-manager.d.ts +4 -3
  78. package/esm/theme/theme-manager.js +19 -9
  79. package/esm/theme/theme-manager.js.map +1 -1
  80. package/esm/theme/tokens.d.ts +0 -1
  81. package/esm/theme/tokens.js +92 -92
  82. package/esm/theme/tokens.js.map +1 -1
  83. package/esm/types/index.d.ts +104 -24
  84. package/esm/types/index.js +8 -3
  85. package/esm/types/index.js.map +1 -0
  86. package/lib/constants/dom.cjs +4 -4
  87. package/lib/constants/dom.cjs.map +1 -1
  88. package/lib/constants/dom.d.cts +25 -0
  89. package/lib/constants/dom.d.ts +3 -19
  90. package/lib/core/chat-manager.cjs +174 -50
  91. package/lib/core/chat-manager.cjs.map +1 -1
  92. package/lib/core/chat-manager.d.cts +45 -0
  93. package/lib/core/chat-manager.d.ts +33 -22
  94. package/lib/core/event-emitter.cjs +14 -7
  95. package/lib/core/event-emitter.cjs.map +1 -1
  96. package/lib/core/event-emitter.d.cts +47 -0
  97. package/lib/core/event-emitter.d.ts +0 -1
  98. package/lib/core/mention-engine.cjs +9 -9
  99. package/lib/core/mention-engine.cjs.map +1 -1
  100. package/lib/core/mention-engine.d.cts +40 -0
  101. package/lib/core/mention-engine.d.ts +1 -2
  102. package/lib/core/message-schema.cjs +202 -0
  103. package/lib/core/message-schema.cjs.map +1 -0
  104. package/lib/core/message-schema.d.cts +19 -0
  105. package/lib/core/message-schema.d.ts +19 -0
  106. package/lib/core/outbox.cjs +162 -0
  107. package/lib/core/outbox.cjs.map +1 -0
  108. package/lib/core/outbox.d.cts +63 -0
  109. package/lib/core/outbox.d.ts +63 -0
  110. package/lib/core/transport.cjs +103 -0
  111. package/lib/core/transport.cjs.map +1 -0
  112. package/lib/core/transport.d.cts +79 -0
  113. package/lib/core/transport.d.ts +79 -0
  114. package/lib/index.cjs +175 -35
  115. package/lib/index.cjs.map +1 -1
  116. package/lib/index.d.cts +33 -0
  117. package/lib/index.d.ts +12 -7
  118. package/lib/renderer/dom-renderer.cjs +316 -61
  119. package/lib/renderer/dom-renderer.cjs.map +1 -1
  120. package/lib/renderer/dom-renderer.d.cts +91 -0
  121. package/lib/renderer/dom-renderer.d.ts +16 -4
  122. package/lib/renderer/style-manager.cjs +92 -62
  123. package/lib/renderer/style-manager.cjs.map +1 -1
  124. package/lib/renderer/style-manager.d.cts +34 -0
  125. package/lib/renderer/style-manager.d.ts +14 -38
  126. package/lib/theme/theme-manager.cjs +19 -9
  127. package/lib/theme/theme-manager.cjs.map +1 -1
  128. package/lib/theme/theme-manager.d.cts +34 -0
  129. package/lib/theme/theme-manager.d.ts +4 -3
  130. package/lib/theme/tokens.cjs +92 -92
  131. package/lib/theme/tokens.cjs.map +1 -1
  132. package/lib/theme/tokens.d.cts +56 -0
  133. package/lib/theme/tokens.d.ts +0 -1
  134. package/lib/types/index.cjs +8 -3
  135. package/lib/types/index.cjs.map +1 -0
  136. package/lib/types/index.d.cts +284 -0
  137. package/lib/types/index.d.ts +104 -24
  138. package/package.json +16 -13
  139. package/es/constants/dom.d.ts.map +0 -1
  140. package/es/core/chat-manager.d.ts.map +0 -1
  141. package/es/core/event-emitter.d.ts.map +0 -1
  142. package/es/core/mention-engine.d.ts.map +0 -1
  143. package/es/index.d.ts.map +0 -1
  144. package/es/renderer/dom-renderer.d.ts.map +0 -1
  145. package/es/renderer/style-manager.d.ts.map +0 -1
  146. package/es/theme/theme-manager.d.ts.map +0 -1
  147. package/es/theme/tokens.d.ts.map +0 -1
  148. package/es/types/index.d.ts.map +0 -1
  149. package/esm/constants/dom.d.ts.map +0 -1
  150. package/esm/core/chat-manager.d.ts.map +0 -1
  151. package/esm/core/event-emitter.d.ts.map +0 -1
  152. package/esm/core/mention-engine.d.ts.map +0 -1
  153. package/esm/index.d.ts.map +0 -1
  154. package/esm/renderer/dom-renderer.d.ts.map +0 -1
  155. package/esm/renderer/style-manager.d.ts.map +0 -1
  156. package/esm/theme/theme-manager.d.ts.map +0 -1
  157. package/esm/theme/tokens.d.ts.map +0 -1
  158. package/esm/types/index.d.ts.map +0 -1
  159. package/lib/constants/dom.d.ts.map +0 -1
  160. package/lib/core/chat-manager.d.ts.map +0 -1
  161. package/lib/core/event-emitter.d.ts.map +0 -1
  162. package/lib/core/mention-engine.d.ts.map +0 -1
  163. package/lib/index.d.ts.map +0 -1
  164. package/lib/renderer/dom-renderer.d.ts.map +0 -1
  165. package/lib/renderer/style-manager.d.ts.map +0 -1
  166. package/lib/theme/theme-manager.d.ts.map +0 -1
  167. package/lib/theme/tokens.d.ts.map +0 -1
  168. package/lib/types/index.d.ts.map +0 -1
@@ -0,0 +1,160 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/chat-core v0.0.2 *
4
+ * Built with rollup *
5
+ * Build time: 2024-10-12 21:52:18 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ import { cloneChatMessage, normalizeChatMessage } from "./message-schema.js";
11
+ //#region src/core/outbox.ts
12
+ var MemoryChatOutboxStorage = class {
13
+ constructor() {
14
+ this.entries = [];
15
+ }
16
+ load() {
17
+ return cloneEntries(this.entries);
18
+ }
19
+ save(entries) {
20
+ this.entries = cloneEntries(entries);
21
+ }
22
+ };
23
+ var ChatOutbox = class {
24
+ constructor(options = {}) {
25
+ this.entries = [];
26
+ this.hydrated = false;
27
+ this.writePromise = Promise.resolve();
28
+ this.storage = options.storage ?? new MemoryChatOutboxStorage();
29
+ this.now = options.now ?? Date.now;
30
+ }
31
+ async hydrate() {
32
+ if (!this.hydrated) {
33
+ this.entries = (await this.storage.load()).map(normalizeEntry);
34
+ this.hydrated = true;
35
+ }
36
+ return this.list();
37
+ }
38
+ list() {
39
+ return cloneEntries(this.entries);
40
+ }
41
+ async enqueue(message) {
42
+ await this.hydrate();
43
+ const normalized = normalizeChatMessage({
44
+ ...message,
45
+ clientMessageId: message.clientMessageId ?? message.id
46
+ });
47
+ const key = getOutboxKey(normalized);
48
+ const existing = this.entries.find((entry2) => entry2.id === key);
49
+ if (existing) return cloneEntry(existing);
50
+ const entry = {
51
+ id: key,
52
+ message: normalized,
53
+ enqueuedAt: this.now(),
54
+ attempts: 0,
55
+ state: "pending"
56
+ };
57
+ this.entries.push(entry);
58
+ await this.persist();
59
+ return cloneEntry(entry);
60
+ }
61
+ async remove(id) {
62
+ await this.hydrate();
63
+ const index = this.entries.findIndex((entry) => entry.id === id);
64
+ if (index < 0) return false;
65
+ this.entries.splice(index, 1);
66
+ await this.persist();
67
+ return true;
68
+ }
69
+ async retry(id) {
70
+ await this.hydrate();
71
+ for (const entry of this.entries) if (!id || entry.id === id) {
72
+ entry.state = "pending";
73
+ entry.lastError = void 0;
74
+ }
75
+ await this.persist();
76
+ }
77
+ async clear() {
78
+ await this.hydrate();
79
+ this.entries = [];
80
+ await this.persist();
81
+ }
82
+ async flush(send, options = {}) {
83
+ await this.hydrate();
84
+ const maxAttempts = Math.max(1, Math.floor(options.maxAttempts ?? 3));
85
+ const concurrency = Math.min(8, Math.max(1, Math.floor(options.concurrency ?? 1)));
86
+ const candidates = this.entries.filter((entry) => entry.state === "pending");
87
+ const sent = [];
88
+ const failed = [];
89
+ let cursor = 0;
90
+ const worker = async () => {
91
+ while (cursor < candidates.length) {
92
+ if (options.signal?.aborted) throw createAbortError();
93
+ const entry = candidates[cursor++];
94
+ entry.attempts += 1;
95
+ try {
96
+ await send(entry.message, {
97
+ signal: options.signal,
98
+ clientMessageId: entry.message.clientMessageId ?? entry.id
99
+ });
100
+ const index = this.entries.findIndex((item) => item.id === entry.id);
101
+ if (index >= 0) this.entries.splice(index, 1);
102
+ sent.push(entry.id);
103
+ } catch (error) {
104
+ entry.lastError = toErrorMessage(error);
105
+ if (entry.attempts >= maxAttempts) entry.state = "failed";
106
+ failed.push({
107
+ id: entry.id,
108
+ error
109
+ });
110
+ }
111
+ await this.persist();
112
+ }
113
+ };
114
+ await Promise.all(Array.from({ length: concurrency }, () => worker()));
115
+ return {
116
+ sent,
117
+ failed,
118
+ remaining: this.list()
119
+ };
120
+ }
121
+ async persist() {
122
+ const snapshot = cloneEntries(this.entries);
123
+ const previous = this.writePromise;
124
+ this.writePromise = previous.then(() => this.storage.save(snapshot));
125
+ await this.writePromise;
126
+ }
127
+ };
128
+ function getOutboxKey(message) {
129
+ return message.clientMessageId ?? message.id;
130
+ }
131
+ function cloneEntry(entry) {
132
+ return {
133
+ ...entry,
134
+ message: cloneChatMessage(entry.message)
135
+ };
136
+ }
137
+ function cloneEntries(entries) {
138
+ return entries.map(cloneEntry);
139
+ }
140
+ function normalizeEntry(entry) {
141
+ const message = normalizeChatMessage(entry.message);
142
+ return {
143
+ id: typeof entry.id === "string" && entry.id ? entry.id : getOutboxKey(message),
144
+ message,
145
+ enqueuedAt: Number.isFinite(entry.enqueuedAt) ? entry.enqueuedAt : Date.now(),
146
+ attempts: Number.isFinite(entry.attempts) ? Math.max(0, Math.floor(entry.attempts)) : 0,
147
+ state: entry.state === "failed" ? "failed" : "pending",
148
+ ...typeof entry.lastError === "string" && { lastError: entry.lastError }
149
+ };
150
+ }
151
+ function toErrorMessage(error) {
152
+ return error instanceof Error ? error.message : String(error);
153
+ }
154
+ function createAbortError() {
155
+ return new DOMException("The operation was aborted.", "AbortError");
156
+ }
157
+ //#endregion
158
+ export { ChatOutbox, MemoryChatOutboxStorage };
159
+ /*! End of @composy/chat-core | Powered by @composy/builder */
160
+ //# sourceMappingURL=outbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.js","names":["entry"],"sources":["../../src/core/outbox.ts"],"sourcesContent":["import type { ChatMessage } from '../types'\nimport { cloneChatMessage, normalizeChatMessage } from './message-schema'\n\n/** 离线 outbox 中的一条待发送消息。 */\nexport interface ChatOutboxEntry {\n id: string\n message: ChatMessage\n enqueuedAt: number\n attempts: number\n state: 'pending' | 'failed'\n lastError?: string\n}\n\n/** outbox 持久化适配器;可接 IndexedDB、SQLite bridge 或业务缓存。 */\nexport interface ChatOutboxStorage {\n load: () => ChatOutboxEntry[] | Promise<ChatOutboxEntry[]>\n save: (entries: ChatOutboxEntry[]) => void | Promise<void>\n}\n\n/** 内存适配器,适合默认运行和单元测试。 */\nexport class MemoryChatOutboxStorage implements ChatOutboxStorage {\n private entries: ChatOutboxEntry[] = []\n\n load(): ChatOutboxEntry[] {\n return cloneEntries(this.entries)\n }\n\n save(entries: ChatOutboxEntry[]): void {\n this.entries = cloneEntries(entries)\n }\n}\n\nexport interface ChatOutboxOptions {\n storage?: ChatOutboxStorage\n now?: () => number\n}\n\nexport interface ChatOutboxFlushOptions {\n signal?: AbortSignal\n maxAttempts?: number\n concurrency?: number\n}\n\nexport interface ChatOutboxFlushResult {\n sent: string[]\n failed: Array<{ id: string; error: unknown }>\n remaining: ChatOutboxEntry[]\n}\n\n/**\n * 幂等离线队列。\n *\n * 队列只负责保存和重试,不假设网络协议;发送函数由 ChatTransportController\n * 或业务层注入。每条消息以 clientMessageId 优先作为幂等键,重复 enqueue 不会产生重复项。\n */\nexport class ChatOutbox {\n private readonly storage: ChatOutboxStorage\n private readonly now: () => number\n private entries: ChatOutboxEntry[] = []\n private hydrated = false\n private writePromise: Promise<void> = Promise.resolve()\n\n constructor(options: ChatOutboxOptions = {}) {\n this.storage = options.storage ?? new MemoryChatOutboxStorage()\n this.now = options.now ?? Date.now\n }\n\n async hydrate(): Promise<ChatOutboxEntry[]> {\n if (!this.hydrated) {\n this.entries = (await this.storage.load()).map(normalizeEntry)\n this.hydrated = true\n }\n return this.list()\n }\n\n list(): ChatOutboxEntry[] {\n return cloneEntries(this.entries)\n }\n\n async enqueue(message: ChatMessage): Promise<ChatOutboxEntry> {\n await this.hydrate()\n const normalized = normalizeChatMessage({\n ...message,\n clientMessageId: message.clientMessageId ?? message.id,\n })\n const key = getOutboxKey(normalized)\n const existing = this.entries.find(entry => entry.id === key)\n if (existing) return cloneEntry(existing)\n\n const entry: ChatOutboxEntry = {\n id: key,\n message: normalized,\n enqueuedAt: this.now(),\n attempts: 0,\n state: 'pending',\n }\n this.entries.push(entry)\n await this.persist()\n return cloneEntry(entry)\n }\n\n async remove(id: string): Promise<boolean> {\n await this.hydrate()\n const index = this.entries.findIndex(entry => entry.id === id)\n if (index < 0) return false\n this.entries.splice(index, 1)\n await this.persist()\n return true\n }\n\n async retry(id?: string): Promise<void> {\n await this.hydrate()\n for (const entry of this.entries) {\n if (!id || entry.id === id) {\n entry.state = 'pending'\n entry.lastError = undefined\n }\n }\n await this.persist()\n }\n\n async clear(): Promise<void> {\n await this.hydrate()\n this.entries = []\n await this.persist()\n }\n\n async flush(\n send: (\n message: ChatMessage,\n options: { signal?: AbortSignal; clientMessageId: string }\n ) => Promise<unknown>,\n options: ChatOutboxFlushOptions = {}\n ): Promise<ChatOutboxFlushResult> {\n await this.hydrate()\n const maxAttempts = Math.max(1, Math.floor(options.maxAttempts ?? 3))\n const concurrency = Math.min(\n 8,\n Math.max(1, Math.floor(options.concurrency ?? 1))\n )\n const candidates = this.entries.filter(entry => entry.state === 'pending')\n const sent: string[] = []\n const failed: Array<{ id: string; error: unknown }> = []\n let cursor = 0\n\n const worker = async () => {\n while (cursor < candidates.length) {\n if (options.signal?.aborted) throw createAbortError()\n const entry = candidates[cursor++]\n entry.attempts += 1\n try {\n await send(entry.message, {\n signal: options.signal,\n clientMessageId: entry.message.clientMessageId ?? entry.id,\n })\n const index = this.entries.findIndex(item => item.id === entry.id)\n if (index >= 0) this.entries.splice(index, 1)\n sent.push(entry.id)\n } catch (error) {\n entry.lastError = toErrorMessage(error)\n if (entry.attempts >= maxAttempts) entry.state = 'failed'\n failed.push({ id: entry.id, error })\n }\n await this.persist()\n }\n }\n\n await Promise.all(Array.from({ length: concurrency }, () => worker()))\n return { sent, failed, remaining: this.list() }\n }\n\n private async persist(): Promise<void> {\n const snapshot = cloneEntries(this.entries)\n const previous = this.writePromise\n this.writePromise = previous.then(() => this.storage.save(snapshot))\n await this.writePromise\n }\n}\n\nfunction getOutboxKey(message: ChatMessage): string {\n return message.clientMessageId ?? message.id\n}\n\nfunction cloneEntry(entry: ChatOutboxEntry): ChatOutboxEntry {\n return {\n ...entry,\n message: cloneChatMessage(entry.message),\n }\n}\n\nfunction cloneEntries(entries: ChatOutboxEntry[]): ChatOutboxEntry[] {\n return entries.map(cloneEntry)\n}\n\nfunction normalizeEntry(entry: ChatOutboxEntry): ChatOutboxEntry {\n const message = normalizeChatMessage(entry.message)\n const id =\n typeof entry.id === 'string' && entry.id ? entry.id : getOutboxKey(message)\n const enqueuedAt = Number.isFinite(entry.enqueuedAt)\n ? entry.enqueuedAt\n : Date.now()\n const attempts = Number.isFinite(entry.attempts)\n ? Math.max(0, Math.floor(entry.attempts))\n : 0\n const state = entry.state === 'failed' ? 'failed' : 'pending'\n return {\n id,\n message,\n enqueuedAt,\n attempts,\n state,\n ...(typeof entry.lastError === 'string' && {\n lastError: entry.lastError,\n }),\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction createAbortError(): DOMException {\n return new DOMException('The operation was aborted.', 'AbortError')\n}\n"],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import type { ChatMessage } from '../types';
2
+ /** transport 连接状态。 */
3
+ export type ChatTransportStatus = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';
4
+ /** 建立 transport 时传入的同步上下文。 */
5
+ export interface ChatTransportContext {
6
+ conversationId?: string;
7
+ cursor?: string;
8
+ signal?: AbortSignal;
9
+ }
10
+ /** transport ack,可携带服务端补全后的消息和同步序号。 */
11
+ export interface ChatTransportAck {
12
+ clientMessageId: string;
13
+ message?: Partial<ChatMessage>;
14
+ sequence?: number;
15
+ cursor?: string;
16
+ }
17
+ /** transport 推送的统一事件协议。 */
18
+ export type ChatTransportEvent = {
19
+ type: 'message';
20
+ message: ChatMessage;
21
+ sequence?: number;
22
+ cursor?: string;
23
+ } | {
24
+ type: 'ack';
25
+ ack: ChatTransportAck;
26
+ } | {
27
+ type: 'cursor';
28
+ cursor: string;
29
+ } | {
30
+ type: 'error';
31
+ error: unknown;
32
+ recoverable?: boolean;
33
+ };
34
+ /** 可由 HTTP/SSE/WebSocket/原生 App bridge 实现的最小 transport 协议。 */
35
+ export interface ChatTransport {
36
+ connect: (context?: ChatTransportContext) => void | Promise<void>;
37
+ disconnect: () => void | Promise<void>;
38
+ send: (message: ChatMessage, options?: {
39
+ signal?: AbortSignal;
40
+ clientMessageId?: string;
41
+ }) => Promise<ChatTransportAck | void>;
42
+ subscribe: (listener: (event: ChatTransportEvent) => void) => () => void;
43
+ onStatusChange?: (listener: (status: ChatTransportStatus) => void) => () => void;
44
+ }
45
+ export interface ChatTransportControllerOptions {
46
+ conversationId?: string;
47
+ cursor?: string;
48
+ onEvent?: (event: ChatTransportEvent) => void;
49
+ onStatusChange?: (status: ChatTransportStatus) => void;
50
+ }
51
+ /**
52
+ * 连接生命周期、游标和外部 transport 事件的统一控制器。
53
+ *
54
+ * Controller 不假设网络实现,负责避免重复 connect、转发状态、保存 cursor,
55
+ * 并在 dispose 后拒绝迟到的异步结果。
56
+ */
57
+ export declare class ChatTransportController {
58
+ private readonly transport;
59
+ private readonly options;
60
+ private status;
61
+ private cursor?;
62
+ private unsubscribeEvents;
63
+ private unsubscribeStatus;
64
+ private destroyed;
65
+ private connectPromise;
66
+ private lifecycle;
67
+ constructor(transport: ChatTransport, options?: ChatTransportControllerOptions);
68
+ getStatus(): ChatTransportStatus;
69
+ getCursor(): string | undefined;
70
+ connect(signal?: AbortSignal): Promise<void>;
71
+ disconnect(): Promise<void>;
72
+ send(message: ChatMessage, options?: {
73
+ signal?: AbortSignal;
74
+ clientMessageId?: string;
75
+ }): Promise<ChatTransportAck | void>;
76
+ dispose(): void;
77
+ private handleEvent;
78
+ private setStatus;
79
+ }
@@ -0,0 +1,102 @@
1
+ /*!
2
+ * ***********************************
3
+ * @composy/chat-core v0.0.2 *
4
+ * Built with rollup *
5
+ * Build time: 2024-10-12 21:52:18 *
6
+ * Build mode: production *
7
+ * Minified: No *
8
+ * ***********************************
9
+ */
10
+ //#region src/core/transport.ts
11
+ var ChatTransportController = class {
12
+ constructor(transport, options = {}) {
13
+ this.status = "idle";
14
+ this.unsubscribeEvents = null;
15
+ this.unsubscribeStatus = null;
16
+ this.destroyed = false;
17
+ this.connectPromise = null;
18
+ this.lifecycle = 0;
19
+ this.transport = transport;
20
+ this.options = options;
21
+ this.cursor = options.cursor;
22
+ }
23
+ getStatus() {
24
+ return this.status;
25
+ }
26
+ getCursor() {
27
+ return this.cursor;
28
+ }
29
+ async connect(signal) {
30
+ if (this.destroyed) throw new Error("Chat transport controller is disposed.");
31
+ if (this.status === "connected") return;
32
+ if (this.connectPromise) return this.connectPromise;
33
+ const lifecycle = ++this.lifecycle;
34
+ this.setStatus("connecting");
35
+ this.connectPromise = (async () => {
36
+ this.unsubscribeEvents?.();
37
+ this.unsubscribeStatus?.();
38
+ this.unsubscribeEvents = this.transport.subscribe((event) => this.handleEvent(event));
39
+ this.unsubscribeStatus = this.transport.onStatusChange?.((status) => this.setStatus(status)) ?? null;
40
+ try {
41
+ await this.transport.connect({
42
+ conversationId: this.options.conversationId,
43
+ cursor: this.cursor,
44
+ signal
45
+ });
46
+ if (this.destroyed || lifecycle !== this.lifecycle) return;
47
+ this.setStatus("connected");
48
+ } catch (error) {
49
+ if (!this.destroyed && lifecycle === this.lifecycle) this.setStatus("error");
50
+ throw error;
51
+ } finally {
52
+ this.connectPromise = null;
53
+ }
54
+ })();
55
+ return this.connectPromise;
56
+ }
57
+ async disconnect() {
58
+ if (this.destroyed) return;
59
+ this.lifecycle += 1;
60
+ this.connectPromise = null;
61
+ try {
62
+ await this.transport.disconnect();
63
+ } finally {
64
+ this.setStatus("disconnected");
65
+ }
66
+ }
67
+ async send(message, options = {}) {
68
+ if (this.destroyed) throw new Error("Chat transport controller is disposed.");
69
+ if (this.status !== "connected") throw new Error(`Chat transport is not connected: ${this.status}`);
70
+ const result = await this.transport.send(message, options);
71
+ if (result && result.cursor) this.cursor = result.cursor;
72
+ return result;
73
+ }
74
+ dispose() {
75
+ if (this.destroyed) return;
76
+ this.destroyed = true;
77
+ this.lifecycle += 1;
78
+ this.unsubscribeEvents?.();
79
+ this.unsubscribeStatus?.();
80
+ this.unsubscribeEvents = null;
81
+ this.unsubscribeStatus = null;
82
+ this.connectPromise = null;
83
+ Promise.resolve(this.transport.disconnect()).catch(() => void 0);
84
+ this.setStatus("disconnected");
85
+ }
86
+ handleEvent(event) {
87
+ if (this.destroyed) return;
88
+ if ("cursor" in event && event.cursor) this.cursor = event.cursor;
89
+ if (event.type === "ack" && event.ack.cursor) this.cursor = event.ack.cursor;
90
+ if (event.type === "error" && !event.recoverable) this.setStatus("error");
91
+ this.options.onEvent?.(event);
92
+ }
93
+ setStatus(status) {
94
+ if (this.status === status) return;
95
+ this.status = status;
96
+ this.options.onStatusChange?.(status);
97
+ }
98
+ };
99
+ //#endregion
100
+ export { ChatTransportController };
101
+ /*! End of @composy/chat-core | Powered by @composy/builder */
102
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","names":[],"sources":["../../src/core/transport.ts"],"sourcesContent":["import type { ChatMessage } from '../types'\n\n/** transport 连接状态。 */\nexport type ChatTransportStatus =\n 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error'\n\n/** 建立 transport 时传入的同步上下文。 */\nexport interface ChatTransportContext {\n conversationId?: string\n cursor?: string\n signal?: AbortSignal\n}\n\n/** transport ack,可携带服务端补全后的消息和同步序号。 */\nexport interface ChatTransportAck {\n clientMessageId: string\n message?: Partial<ChatMessage>\n sequence?: number\n cursor?: string\n}\n\n/** transport 推送的统一事件协议。 */\nexport type ChatTransportEvent =\n | {\n type: 'message'\n message: ChatMessage\n sequence?: number\n cursor?: string\n }\n | { type: 'ack'; ack: ChatTransportAck }\n | { type: 'cursor'; cursor: string }\n | { type: 'error'; error: unknown; recoverable?: boolean }\n\n/** 可由 HTTP/SSE/WebSocket/原生 App bridge 实现的最小 transport 协议。 */\nexport interface ChatTransport {\n connect: (context?: ChatTransportContext) => void | Promise<void>\n disconnect: () => void | Promise<void>\n send: (\n message: ChatMessage,\n options?: { signal?: AbortSignal; clientMessageId?: string }\n ) => Promise<ChatTransportAck | void>\n subscribe: (listener: (event: ChatTransportEvent) => void) => () => void\n onStatusChange?: (\n listener: (status: ChatTransportStatus) => void\n ) => () => void\n}\n\nexport interface ChatTransportControllerOptions {\n conversationId?: string\n cursor?: string\n onEvent?: (event: ChatTransportEvent) => void\n onStatusChange?: (status: ChatTransportStatus) => void\n}\n\n/**\n * 连接生命周期、游标和外部 transport 事件的统一控制器。\n *\n * Controller 不假设网络实现,负责避免重复 connect、转发状态、保存 cursor,\n * 并在 dispose 后拒绝迟到的异步结果。\n */\nexport class ChatTransportController {\n private readonly transport: ChatTransport\n private readonly options: ChatTransportControllerOptions\n private status: ChatTransportStatus = 'idle'\n private cursor?: string\n private unsubscribeEvents: (() => void) | null = null\n private unsubscribeStatus: (() => void) | null = null\n private destroyed = false\n private connectPromise: Promise<void> | null = null\n private lifecycle = 0\n\n constructor(\n transport: ChatTransport,\n options: ChatTransportControllerOptions = {}\n ) {\n this.transport = transport\n this.options = options\n this.cursor = options.cursor\n }\n\n getStatus(): ChatTransportStatus {\n return this.status\n }\n\n getCursor(): string | undefined {\n return this.cursor\n }\n\n async connect(signal?: AbortSignal): Promise<void> {\n if (this.destroyed)\n throw new Error('Chat transport controller is disposed.')\n if (this.status === 'connected') return\n if (this.connectPromise) return this.connectPromise\n\n const lifecycle = ++this.lifecycle\n this.setStatus('connecting')\n this.connectPromise = (async () => {\n this.unsubscribeEvents?.()\n this.unsubscribeStatus?.()\n this.unsubscribeEvents = this.transport.subscribe(event =>\n this.handleEvent(event)\n )\n this.unsubscribeStatus =\n this.transport.onStatusChange?.(status => this.setStatus(status)) ??\n null\n try {\n await this.transport.connect({\n conversationId: this.options.conversationId,\n cursor: this.cursor,\n signal,\n })\n if (this.destroyed || lifecycle !== this.lifecycle) return\n this.setStatus('connected')\n } catch (error) {\n if (!this.destroyed && lifecycle === this.lifecycle) {\n this.setStatus('error')\n }\n throw error\n } finally {\n this.connectPromise = null\n }\n })()\n\n return this.connectPromise\n }\n\n async disconnect(): Promise<void> {\n if (this.destroyed) return\n this.lifecycle += 1\n this.connectPromise = null\n try {\n await this.transport.disconnect()\n } finally {\n this.setStatus('disconnected')\n }\n }\n\n async send(\n message: ChatMessage,\n options: { signal?: AbortSignal; clientMessageId?: string } = {}\n ): Promise<ChatTransportAck | void> {\n if (this.destroyed)\n throw new Error('Chat transport controller is disposed.')\n if (this.status !== 'connected') {\n throw new Error(`Chat transport is not connected: ${this.status}`)\n }\n const result = await this.transport.send(message, options)\n if (result && result.cursor) this.cursor = result.cursor\n return result\n }\n\n dispose(): void {\n if (this.destroyed) return\n this.destroyed = true\n this.lifecycle += 1\n this.unsubscribeEvents?.()\n this.unsubscribeStatus?.()\n this.unsubscribeEvents = null\n this.unsubscribeStatus = null\n this.connectPromise = null\n void Promise.resolve(this.transport.disconnect()).catch(() => undefined)\n this.setStatus('disconnected')\n }\n\n private handleEvent(event: ChatTransportEvent): void {\n if (this.destroyed) return\n if ('cursor' in event && event.cursor) this.cursor = event.cursor\n if (event.type === 'ack' && event.ack.cursor) {\n this.cursor = event.ack.cursor\n }\n if (event.type === 'error' && !event.recoverable) this.setStatus('error')\n this.options.onEvent?.(event)\n }\n\n private setStatus(status: ChatTransportStatus): void {\n if (this.status === status) return\n this.status = status\n this.options.onStatusChange?.(status)\n }\n}\n"],"mappings":";;;;;;;;;;AA4DO,IAAM,0BAAN,MAA8B;CAWnC,YACE,WACA,UAA0C,CAAC,GAC3C;EAXF,KAAQ,SAA8B;EAEtC,KAAQ,oBAAyC;EACjD,KAAQ,oBAAyC;EACjD,KAAQ,YAAY;EACpB,KAAQ,iBAAuC;EAC/C,KAAQ,YAAY;EAMlB,KAAK,YAAY;EACjB,KAAK,UAAU;EACf,KAAK,SAAS,QAAQ;CACxB;CAEA,YAAiC;EAC/B,OAAO,KAAK;CACd;CAEA,YAAgC;EAC9B,OAAO,KAAK;CACd;CAEA,MAAM,QAAQ,QAAqC;EACjD,IAAI,KAAK,WACP,MAAM,IAAI,MAAM,wCAAwC;EAC1D,IAAI,KAAK,WAAW,aAAa;EACjC,IAAI,KAAK,gBAAgB,OAAO,KAAK;EAErC,MAAM,YAAY,EAAE,KAAK;EACzB,KAAK,UAAU,YAAY;EAC3B,KAAK,kBAAkB,YAAY;GACjC,KAAK,oBAAoB;GACzB,KAAK,oBAAoB;GACzB,KAAK,oBAAoB,KAAK,UAAU,WAAU,UAChD,KAAK,YAAY,KAAK,CACxB;GACA,KAAK,oBACH,KAAK,UAAU,kBAAiB,WAAU,KAAK,UAAU,MAAM,CAAC,KAChE;GACF,IAAI;IACF,MAAM,KAAK,UAAU,QAAQ;KAC3B,gBAAgB,KAAK,QAAQ;KAC7B,QAAQ,KAAK;KACb;IACF,CAAC;IACD,IAAI,KAAK,aAAa,cAAc,KAAK,WAAW;IACpD,KAAK,UAAU,WAAW;GAC5B,SAAS,OAAO;IACd,IAAI,CAAC,KAAK,aAAa,cAAc,KAAK,WACxC,KAAK,UAAU,OAAO;IAExB,MAAM;GACR,UAAE;IACA,KAAK,iBAAiB;GACxB;EACF,EAAA,CAAG;EAEH,OAAO,KAAK;CACd;CAEA,MAAM,aAA4B;EAChC,IAAI,KAAK,WAAW;EACpB,KAAK,aAAa;EAClB,KAAK,iBAAiB;EACtB,IAAI;GACF,MAAM,KAAK,UAAU,WAAW;EAClC,UAAE;GACA,KAAK,UAAU,cAAc;EAC/B;CACF;CAEA,MAAM,KACJ,SACA,UAA8D,CAAC,GAC7B;EAClC,IAAI,KAAK,WACP,MAAM,IAAI,MAAM,wCAAwC;EAC1D,IAAI,KAAK,WAAW,aAClB,MAAM,IAAI,MAAM,oCAAoC,KAAK,QAAQ;EAEnE,MAAM,SAAS,MAAM,KAAK,UAAU,KAAK,SAAS,OAAO;EACzD,IAAI,UAAU,OAAO,QAAQ,KAAK,SAAS,OAAO;EAClD,OAAO;CACT;CAEA,UAAgB;EACd,IAAI,KAAK,WAAW;EACpB,KAAK,YAAY;EACjB,KAAK,aAAa;EAClB,KAAK,oBAAoB;EACzB,KAAK,oBAAoB;EACzB,KAAK,oBAAoB;EACzB,KAAK,oBAAoB;EACzB,KAAK,iBAAiB;EACtB,QAAa,QAAQ,KAAK,UAAU,WAAW,CAAC,CAAA,CAAE,YAAY,KAAA,CAAS;EACvE,KAAK,UAAU,cAAc;CAC/B;CAEQ,YAAY,OAAiC;EACnD,IAAI,KAAK,WAAW;EACpB,IAAI,YAAY,SAAS,MAAM,QAAQ,KAAK,SAAS,MAAM;EAC3D,IAAI,MAAM,SAAS,SAAS,MAAM,IAAI,QACpC,KAAK,SAAS,MAAM,IAAI;EAE1B,IAAI,MAAM,SAAS,WAAW,CAAC,MAAM,aAAa,KAAK,UAAU,OAAO;EACxE,KAAK,QAAQ,UAAU,KAAK;CAC9B;CAEQ,UAAU,QAAmC;EACnD,IAAI,KAAK,WAAW,QAAQ;EAC5B,KAAK,SAAS;EACd,KAAK,QAAQ,iBAAiB,MAAM;CACtC;AACF"}
package/esm/index.d.ts CHANGED
@@ -10,19 +10,24 @@
10
10
  */
11
11
  import type { ChatConfig, ChatInstance } from './types';
12
12
  export declare const version = "0.1.0";
13
- export * from './types';
14
- export { EventEmitter } from './core/event-emitter';
13
+ export { COMPONENT_CSS_VAR_PREFIX, cx, DEFAULT_CLASS_PREFIX, getStyleElementId, normalizeClassPrefix, STYLE_ELEMENT_ID, } from './constants/dom';
15
14
  export { ChatManager } from './core/chat-manager';
15
+ export type { MessageMergeOptions, MessageMergeResult, StreamAppendOptions, } from './core/chat-manager';
16
+ export { EventEmitter } from './core/event-emitter';
16
17
  export { MentionEngine } from './core/mention-engine';
17
18
  export type { MentionState } from './core/mention-engine';
19
+ export { cloneChatMessage, compareChatMessages, normalizeChatContentBlocks, normalizeChatMessage, normalizeChatMessages, } from './core/message-schema';
20
+ export { ChatOutbox, MemoryChatOutboxStorage } from './core/outbox';
21
+ export type { ChatOutboxEntry, ChatOutboxFlushOptions, ChatOutboxFlushResult, ChatOutboxOptions, ChatOutboxStorage, } from './core/outbox';
22
+ export { ChatTransportController } from './core/transport';
23
+ export type { ChatTransport, ChatTransportAck, ChatTransportContext, ChatTransportControllerOptions, ChatTransportEvent, ChatTransportStatus, } from './core/transport';
24
+ export { DOMRenderer } from './renderer/dom-renderer';
25
+ export { cls, clsx, injectStyles, removeStyles, updateStyles, } from './renderer/style-manager';
18
26
  export { ThemeManager } from './theme/theme-manager';
19
27
  export type { ThemeTokens } from './theme/tokens';
20
- export { lightTokens, darkTokens } from './theme/tokens';
21
- export { DOMRenderer } from './renderer/dom-renderer';
22
- export { injectStyles, updateStyles, removeStyles, cls, clsx } from './renderer/style-manager';
23
- export { DEFAULT_CLASS_PREFIX, COMPONENT_CSS_VAR_PREFIX, STYLE_ELEMENT_ID, getStyleElementId, normalizeClassPrefix, cx, } from './constants/dom';
28
+ export { darkTokens, lightTokens } from './theme/tokens';
29
+ export * from './types';
24
30
  /**
25
31
  * 创建聊天实例
26
32
  */
27
33
  export declare function createChat(config: ChatConfig): ChatInstance;
28
- //# sourceMappingURL=index.d.ts.map