@awiki/dsh-plugin 0.2.4 → 0.2.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.
Files changed (115) hide show
  1. package/README.md +80 -11
  2. package/README.zh.md +67 -12
  3. package/THIRD_PARTY_NOTICES.md +8 -1
  4. package/cordis.patch.yml +13 -0
  5. package/lib/client.js +8223 -1939
  6. package/lib/client.js.map +1 -1
  7. package/lib/index.js +1486 -59
  8. package/lib/model-proxy-contract.js +89 -0
  9. package/lib/model-proxy.js +383 -0
  10. package/lib/provider.js +2 -1
  11. package/lib/sdk-adapter-DKgkyApB.mjs +669 -0
  12. package/lib/typert.host.js +470 -482
  13. package/lib/typert.remote-client.d.ts +15 -1
  14. package/lib/typert.remote-client.d.ts.map +1 -1
  15. package/lib/typert.remote-client.js +469 -103
  16. package/lib/types/attachment-cache.d.ts +28 -0
  17. package/lib/types/attachment-cache.d.ts.map +1 -0
  18. package/lib/types/attachment-cache.js +194 -0
  19. package/lib/types/attachment-cache.js.map +1 -0
  20. package/lib/types/client/AwikiMail.d.ts +14 -0
  21. package/lib/types/client/AwikiMail.d.ts.map +1 -0
  22. package/lib/types/client/AwikiMail.js +260 -0
  23. package/lib/types/client/AwikiMail.js.map +1 -0
  24. package/lib/types/client/AwikiOnboarding.d.ts +22 -0
  25. package/lib/types/client/AwikiOnboarding.d.ts.map +1 -0
  26. package/lib/types/client/AwikiOnboarding.js +87 -0
  27. package/lib/types/client/AwikiOnboarding.js.map +1 -0
  28. package/lib/types/client/AwikiOverlay.d.ts +15 -0
  29. package/lib/types/client/AwikiOverlay.d.ts.map +1 -1
  30. package/lib/types/client/AwikiOverlay.js +251 -20
  31. package/lib/types/client/AwikiOverlay.js.map +1 -1
  32. package/lib/types/client/AwikiSettingsSection.d.ts +20 -4
  33. package/lib/types/client/AwikiSettingsSection.d.ts.map +1 -1
  34. package/lib/types/client/AwikiSettingsSection.js +279 -23
  35. package/lib/types/client/AwikiSettingsSection.js.map +1 -1
  36. package/lib/types/client/RechargeComingSoonDialog.d.ts +11 -0
  37. package/lib/types/client/RechargeComingSoonDialog.d.ts.map +1 -0
  38. package/lib/types/client/RechargeComingSoonDialog.js +8 -0
  39. package/lib/types/client/RechargeComingSoonDialog.js.map +1 -0
  40. package/lib/types/client/controller.d.ts +82 -4
  41. package/lib/types/client/controller.d.ts.map +1 -1
  42. package/lib/types/client/controller.js +517 -74
  43. package/lib/types/client/controller.js.map +1 -1
  44. package/lib/types/client/image-cache.d.ts +20 -0
  45. package/lib/types/client/image-cache.d.ts.map +1 -0
  46. package/lib/types/client/image-cache.js +177 -0
  47. package/lib/types/client/image-cache.js.map +1 -0
  48. package/lib/types/client/index.d.ts +2 -0
  49. package/lib/types/client/index.d.ts.map +1 -1
  50. package/lib/types/client/index.js +84 -41
  51. package/lib/types/client/index.js.map +1 -1
  52. package/lib/types/client/model-account-settings-availability.d.ts +4 -0
  53. package/lib/types/client/model-account-settings-availability.d.ts.map +1 -0
  54. package/lib/types/client/model-account-settings-availability.js +4 -0
  55. package/lib/types/client/model-account-settings-availability.js.map +1 -0
  56. package/lib/types/client/model-availability-controller.d.ts +27 -0
  57. package/lib/types/client/model-availability-controller.d.ts.map +1 -0
  58. package/lib/types/client/model-availability-controller.js +111 -0
  59. package/lib/types/client/model-availability-controller.js.map +1 -0
  60. package/lib/types/client/model-proxy-controller.d.ts +41 -0
  61. package/lib/types/client/model-proxy-controller.d.ts.map +1 -0
  62. package/lib/types/client/model-proxy-controller.js +241 -0
  63. package/lib/types/client/model-proxy-controller.js.map +1 -0
  64. package/lib/types/client/recharge-availability.d.ts +6 -0
  65. package/lib/types/client/recharge-availability.d.ts.map +1 -0
  66. package/lib/types/client/recharge-availability.js +6 -0
  67. package/lib/types/client/recharge-availability.js.map +1 -0
  68. package/lib/types/client/settings-locales.d.ts +1 -1
  69. package/lib/types/client/settings-locales.d.ts.map +1 -1
  70. package/lib/types/client/settings-locales.js +180 -2
  71. package/lib/types/client/settings-locales.js.map +1 -1
  72. package/lib/types/client/slots.d.ts +15 -2
  73. package/lib/types/client/slots.d.ts.map +1 -1
  74. package/lib/types/index.d.ts +56 -2
  75. package/lib/types/index.d.ts.map +1 -1
  76. package/lib/types/index.js +462 -31
  77. package/lib/types/index.js.map +1 -1
  78. package/lib/types/listener-state.d.ts +23 -0
  79. package/lib/types/listener-state.d.ts.map +1 -0
  80. package/lib/types/listener-state.js +124 -0
  81. package/lib/types/listener-state.js.map +1 -0
  82. package/lib/types/listener.d.ts +96 -0
  83. package/lib/types/listener.d.ts.map +1 -0
  84. package/lib/types/listener.js +575 -0
  85. package/lib/types/listener.js.map +1 -0
  86. package/lib/types/mail.d.ts +8 -0
  87. package/lib/types/mail.d.ts.map +1 -0
  88. package/lib/types/mail.js +75 -0
  89. package/lib/types/mail.js.map +1 -0
  90. package/lib/types/model-proxy-contract.d.ts +61 -0
  91. package/lib/types/model-proxy-contract.d.ts.map +1 -0
  92. package/lib/types/model-proxy-contract.js +129 -0
  93. package/lib/types/model-proxy-contract.js.map +1 -0
  94. package/lib/types/model-proxy.d.ts +14 -0
  95. package/lib/types/model-proxy.d.ts.map +1 -0
  96. package/lib/types/model-proxy.js +371 -0
  97. package/lib/types/model-proxy.js.map +1 -0
  98. package/lib/types/provider-api.d.ts +78 -2
  99. package/lib/types/provider-api.d.ts.map +1 -1
  100. package/lib/types/provider.d.ts.map +1 -1
  101. package/lib/types/provider.js +1 -0
  102. package/lib/types/provider.js.map +1 -1
  103. package/lib/types/sdk-adapter.d.ts +26 -2
  104. package/lib/types/sdk-adapter.d.ts.map +1 -1
  105. package/lib/types/sdk-adapter.js +380 -24
  106. package/lib/types/sdk-adapter.js.map +1 -1
  107. package/lib/types/tools.d.ts +10 -0
  108. package/lib/types/tools.d.ts.map +1 -1
  109. package/lib/types/tools.js +98 -0
  110. package/lib/types/tools.js.map +1 -1
  111. package/lib/types/types.d.ts +103 -1
  112. package/lib/types/types.d.ts.map +1 -1
  113. package/lib/types/types.js.map +1 -1
  114. package/package.json +30 -5
  115. package/lib/sdk-adapter-DK6RqV-c.mjs +0 -355
@@ -0,0 +1,669 @@
1
+ //#region lib/types/sdk-adapter.js
2
+ /** Rust IM Core adapter that copies native values into Host-owned public DTOs. */
3
+ const GROUP_LOOKUP_LIMIT = 100;
4
+ const MAX_GROUP_LOOKUP_PAGES = 20;
5
+ const RUST_FAILURE_CODES = {
6
+ invalid_input: "invalid-request",
7
+ invalid_state_root: "invalid-request",
8
+ invalid_cursor: "invalid-request",
9
+ identity_required: "not-registered",
10
+ identity_not_found: "not-registered",
11
+ identity_not_ready: "not-registered",
12
+ auth_required: "not-registered",
13
+ invalid_otp: "invalid-otp",
14
+ challenge_expired: "challenge-expired",
15
+ handle_unavailable: "handle-unavailable",
16
+ not_found: "not-found",
17
+ permission_denied: "forbidden",
18
+ auth_revoked: "forbidden",
19
+ conflict: "conflict",
20
+ join_required: "handle-unavailable",
21
+ state_in_use: "conflict",
22
+ rate_limited: "rate-limited",
23
+ timeout: "network",
24
+ transport_unavailable: "network",
25
+ sync_failed: "network",
26
+ session_expired: "network",
27
+ attachment_transfer_network: "network"
28
+ };
29
+ /** Closed provider error consumed by the Host's fixed public failure mapping. */
30
+ var AwikiSdkError = class extends Error {
31
+ code;
32
+ name = "AwikiSdkError";
33
+ constructor(code) {
34
+ super(`AWiki SDK operation failed: ${code}`);
35
+ this.code = code;
36
+ }
37
+ };
38
+ function fail(code = "remote") {
39
+ throw new AwikiSdkError(code);
40
+ }
41
+ function mapError(error, ambiguousSend = false) {
42
+ if (error instanceof AwikiSdkError) throw error;
43
+ let code = "remote";
44
+ try {
45
+ if (typeof error === "object" && error !== null) {
46
+ const value = error;
47
+ if (value.name === "ImCoreNodeError" && typeof value.code === "string") code = ambiguousSend && (value.code === "timeout" || value.code === "transport_unavailable") ? "delivery-unknown" : RUST_FAILURE_CODES[value.code] ?? "remote";
48
+ }
49
+ } catch {}
50
+ fail(code);
51
+ }
52
+ function safeInteger(value, minimum = 0) {
53
+ if (!/^(?:0|[1-9]\d*)$/u.test(value)) fail();
54
+ const parsed = Number(value);
55
+ if (!Number.isSafeInteger(parsed) || parsed < minimum) fail();
56
+ return parsed;
57
+ }
58
+ function timestamp(value) {
59
+ const parsed = Date.parse(value);
60
+ if (!Number.isSafeInteger(parsed)) fail();
61
+ return parsed;
62
+ }
63
+ function required(value) {
64
+ if (value === void 0 || value.trim().length === 0) fail();
65
+ return value;
66
+ }
67
+ /** Recover the browser's exact optimistic message identity without widening the Remote schema. */
68
+ function browserMessageId(idempotencyKey) {
69
+ return /^msg-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u.test(idempotencyKey) ? idempotencyKey : void 0;
70
+ }
71
+ function remoteString(value, maxBytes) {
72
+ if (typeof value !== "string" || value.includes("\0") || Buffer.byteLength(value, "utf8") > maxBytes) fail();
73
+ return value;
74
+ }
75
+ function remoteOptionalString(value, maxBytes) {
76
+ return value === void 0 ? void 0 : remoteString(value, maxBytes);
77
+ }
78
+ function mailToken(value, maxCharacters) {
79
+ if (typeof value !== "string" || value.length === 0 || value.trim() !== value || Array.from(value).length > maxCharacters || /[\u0000-\u001f\u007f-\u009f]/u.test(value)) fail();
80
+ return value;
81
+ }
82
+ function mailAddress(value) {
83
+ if (typeof value !== "string") fail();
84
+ const length = Array.from(value).length;
85
+ if (length < 3 || length > 320 || !value.includes("@") || /[\s\u0000-\u001f\u007f-\u009f]/u.test(value)) fail();
86
+ return value;
87
+ }
88
+ function mailAddresses(value) {
89
+ if (!Array.isArray(value) || value.length > 100) fail();
90
+ return value.map(mailAddress);
91
+ }
92
+ function mailTimestamp(value) {
93
+ if (value === void 0) return void 0;
94
+ const copied = remoteString(value, 64);
95
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/u.test(copied) || !Number.isFinite(Date.parse(copied))) fail();
96
+ return copied;
97
+ }
98
+ function uint32(value) {
99
+ if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) fail();
100
+ return value;
101
+ }
102
+ function boolean(value) {
103
+ if (typeof value !== "boolean") fail();
104
+ return value;
105
+ }
106
+ function mailSummary(value) {
107
+ const receivedAt = mailTimestamp(value.receivedAt);
108
+ const sentAt = mailTimestamp(value.sentAt);
109
+ const folder = value.folder === void 0 ? void 0 : mailToken(value.folder, 64);
110
+ const preview = remoteOptionalString(value.preview, 4096);
111
+ const attachmentCount = value.attachmentCount === void 0 ? void 0 : uint32(value.attachmentCount);
112
+ return {
113
+ id: mailToken(value.id, 2048),
114
+ ...folder === void 0 ? {} : { folder },
115
+ from: mailAddresses(value.from),
116
+ to: mailAddresses(value.to),
117
+ cc: mailAddresses(value.cc),
118
+ subject: remoteString(value.subject, 1024),
119
+ subjectTruncated: boolean(value.subjectTruncated),
120
+ ...preview === void 0 ? {} : { preview },
121
+ previewTruncated: boolean(value.previewTruncated),
122
+ ...receivedAt === void 0 ? {} : { receivedAt },
123
+ ...sentAt === void 0 ? {} : { sentAt },
124
+ unread: boolean(value.unread),
125
+ hasAttachments: boolean(value.hasAttachments),
126
+ ...attachmentCount === void 0 ? {} : { attachmentCount }
127
+ };
128
+ }
129
+ function mailAttachment(value) {
130
+ const fileName = remoteOptionalString(value.fileName, 512);
131
+ const contentType = remoteOptionalString(value.contentType, 255);
132
+ const sizeBytes = value.sizeBytes === void 0 ? void 0 : remoteString(value.sizeBytes, 20);
133
+ if (sizeBytes !== void 0 && !/^(?:0|[1-9]\d*)$/u.test(sizeBytes)) fail();
134
+ return {
135
+ index: uint32(value.index),
136
+ ...fileName === void 0 ? {} : { fileName },
137
+ ...contentType === void 0 ? {} : { contentType },
138
+ ...sizeBytes === void 0 ? {} : { sizeBytes }
139
+ };
140
+ }
141
+ function mailAccount(value) {
142
+ const mailboxAddress = value.mailboxAddress === void 0 ? void 0 : mailAddress(value.mailboxAddress);
143
+ const displayName = remoteOptionalString(value.displayName, 512);
144
+ const status = remoteOptionalString(value.status, 128);
145
+ return {
146
+ ...mailboxAddress === void 0 ? {} : { mailboxAddress },
147
+ ...displayName === void 0 ? {} : { displayName },
148
+ ...status === void 0 ? {} : { status }
149
+ };
150
+ }
151
+ function mailInbox(value) {
152
+ if (!Array.isArray(value.items) || value.items.length > 100) fail();
153
+ const hasMore = boolean(value.hasMore);
154
+ const nextOffset = value.nextOffset === void 0 ? void 0 : uint32(value.nextOffset);
155
+ if (hasMore && nextOffset === void 0 || !hasMore && nextOffset !== void 0) fail();
156
+ return {
157
+ items: value.items.map(mailSummary),
158
+ ...nextOffset === void 0 ? {} : { nextOffset },
159
+ hasMore
160
+ };
161
+ }
162
+ function mailMessage(value) {
163
+ if (!Array.isArray(value.attachments) || value.attachments.length > 100) fail();
164
+ const bodyText = remoteOptionalString(value.bodyText, 65536);
165
+ return {
166
+ summary: mailSummary(value.summary),
167
+ ...bodyText === void 0 ? {} : { bodyText },
168
+ bodyTruncated: boolean(value.bodyTruncated),
169
+ hasHtmlBody: boolean(value.hasHtmlBody),
170
+ attachments: value.attachments.map(mailAttachment)
171
+ };
172
+ }
173
+ function sha256(value) {
174
+ const provided = value.sha256Hex?.toLowerCase();
175
+ if (provided !== void 0 && /^[a-f0-9]{64}$/u.test(provided)) return provided;
176
+ try {
177
+ const bytes = Buffer.from(value.digestB64u, "base64url");
178
+ if (bytes.byteLength === 32 && bytes.toString("base64url") === value.digestB64u) return bytes.toString("hex");
179
+ } catch {}
180
+ fail();
181
+ }
182
+ /** Copy one native identity without retaining provider-owned objects. */
183
+ function identity(value) {
184
+ return {
185
+ handle: required(value.handle),
186
+ did: required(value.did),
187
+ ...value.displayName === void 0 ? {} : { displayName: value.displayName },
188
+ registeredAt: safeInteger(value.registeredAtMs)
189
+ };
190
+ }
191
+ /** Copy one native attachment and normalize its decimal/digest encodings. */
192
+ function attachment(value) {
193
+ return {
194
+ id: required(value.id),
195
+ fileName: required(value.fileName),
196
+ mimeType: required(value.mimeType),
197
+ size: safeInteger(value.sizeBytes),
198
+ sha256: sha256(value)
199
+ };
200
+ }
201
+ function preview(value) {
202
+ if (value === void 0) return void 0;
203
+ switch (value.content.kind) {
204
+ case "text": return value.content.text;
205
+ case "attachment": {
206
+ const fileName = value.content.attachment?.fileName;
207
+ return fileName === void 0 ? void 0 : `[附件] ${fileName}`;
208
+ }
209
+ default: return;
210
+ }
211
+ }
212
+ /** Provider-only protocol events are not part of the browser's text/attachment history contract. */
213
+ function displayableMessage(value) {
214
+ return value.content.kind === "text" || value.content.kind === "attachment";
215
+ }
216
+ /** Copy one native page and brand its opaque cursor for the Host API. */
217
+ function page(value, copy) {
218
+ return {
219
+ items: value.items.map(copy),
220
+ ...value.nextCursor === void 0 ? {} : { nextCursor: String(value.nextCursor) },
221
+ hasMore: value.hasMore
222
+ };
223
+ }
224
+ function httpHeaders(headers) {
225
+ return headers.map((header) => ({
226
+ name: String(header.name),
227
+ value: String(header.value)
228
+ }));
229
+ }
230
+ function externalHttpAttempt(value) {
231
+ return {
232
+ targetUrl: String(value.targetUrl),
233
+ method: String(value.method),
234
+ headerPatch: httpHeaders(value.headerPatch),
235
+ retryCount: value.retryCount,
236
+ async handleResponse(response) {
237
+ try {
238
+ const retry = await value.handleResponse({
239
+ statusCode: response.statusCode,
240
+ headers: response.headers.map((header) => ({
241
+ name: header.name,
242
+ value: header.value
243
+ }))
244
+ });
245
+ return retry === null ? null : externalHttpAttempt(retry);
246
+ } catch (error) {
247
+ mapError(error);
248
+ }
249
+ }
250
+ };
251
+ }
252
+ /** Adapt the Rust Node bridge to the frozen Host provider interface. */
253
+ var RustSdkAdapter = class {
254
+ client;
255
+ attachmentConversations = /* @__PURE__ */ new Map();
256
+ disposal;
257
+ listener;
258
+ constructor(client) {
259
+ this.client = Promise.resolve(client);
260
+ this.listener = {
261
+ syncNow: (reason) => this.listenerSyncNow(reason),
262
+ startRealtime: () => this.listenerStartRealtime(),
263
+ listConversations: (request) => this.listenerConversations(request),
264
+ getHistory: (request) => this.listenerHistory(request),
265
+ markConversationRead: (conversationId) => this.markConversationRead(conversationId),
266
+ sendText: (request) => this.sendText(request)
267
+ };
268
+ }
269
+ async run(operation, ambiguousSend = false) {
270
+ try {
271
+ return await operation(await this.client);
272
+ } catch (error) {
273
+ mapError(error, ambiguousSend);
274
+ }
275
+ }
276
+ async displayableMessages(client, values) {
277
+ const messages = values.filter(displayableMessage);
278
+ const peers = [...new Set(messages.filter((message) => message.conversationKind === "group" && !message.outgoing && message.senderHandle === void 0 && message.senderDisplayName === void 0).map((message) => message.senderDid))];
279
+ if (peers.length === 0) return [...messages];
280
+ const profiles = await client.hydrateDisplayProfiles({ peers });
281
+ const byDid = /* @__PURE__ */ new Map();
282
+ for (const profile of profiles) if (profile.did !== void 0) byDid.set(profile.did, profile);
283
+ return messages.map((message) => {
284
+ const profile = byDid.get(message.senderDid);
285
+ if (profile === void 0) return message;
286
+ return {
287
+ ...message,
288
+ ...profile.handle === void 0 ? {} : { senderHandle: profile.handle },
289
+ ...profile.displayName === void 0 ? {} : { senderDisplayName: profile.displayName }
290
+ };
291
+ });
292
+ }
293
+ /**
294
+ * Join the persisted Core peer-profile projection onto direct roster rows.
295
+ * The conversation registry intentionally keeps routing identifiers separate
296
+ * from display metadata, so a bare roster row may otherwise regress to a Handle.
297
+ */
298
+ async displayableConversations(client, values) {
299
+ const peers = [...new Set(values.filter((conversation) => conversation.kind === "direct" && conversation.peerDid !== void 0).map((conversation) => conversation.peerDid))];
300
+ const profiles = peers.length === 0 ? [] : await client.hydrateDisplayProfiles({ peers });
301
+ const byPeer = /* @__PURE__ */ new Map();
302
+ for (const [index, profile] of profiles.entries()) {
303
+ const requested = peers[index];
304
+ if (requested !== void 0) byPeer.set(requested, profile);
305
+ if (profile.did !== void 0) byPeer.set(profile.did, profile);
306
+ if (profile.handle !== void 0) byPeer.set(profile.handle, profile);
307
+ }
308
+ return values.map((value) => this.conversation(value, value.kind === "direct" ? byPeer.get(value.peerDid ?? "") ?? byPeer.get(value.peerHandle ?? "") : void 0));
309
+ }
310
+ message(value) {
311
+ const sentAt = value.sentAt === void 0 ? fail() : timestamp(value.sentAt);
312
+ const common = {
313
+ id: required(value.id),
314
+ conversationId: required(value.conversationId),
315
+ conversationKind: value.conversationKind,
316
+ senderDid: required(value.senderDid),
317
+ ...value.senderHandle === void 0 ? {} : { senderHandle: value.senderHandle },
318
+ ...value.senderDisplayName === void 0 ? {} : { senderDisplayName: value.senderDisplayName },
319
+ sentAt,
320
+ outgoing: value.outgoing
321
+ };
322
+ switch (value.content.kind) {
323
+ case "text": return {
324
+ ...common,
325
+ content: {
326
+ kind: "text",
327
+ text: required(value.content.text)
328
+ }
329
+ };
330
+ case "attachment": {
331
+ if (value.content.attachment === void 0) fail();
332
+ const copied = attachment(value.content.attachment);
333
+ this.attachmentConversations.set(`${String(common.id)}\u0000${String(copied.id)}`, String(common.conversationId));
334
+ return {
335
+ ...common,
336
+ content: {
337
+ kind: "attachment",
338
+ attachment: copied,
339
+ ...value.content.caption === void 0 ? {} : { caption: value.content.caption }
340
+ }
341
+ };
342
+ }
343
+ default: fail();
344
+ }
345
+ }
346
+ conversation(value, profile) {
347
+ const id = required(value.id);
348
+ const displayName = profile?.displayName?.trim();
349
+ const profileHandle = profile?.handle?.trim();
350
+ const title = displayName === void 0 || displayName.length === 0 ? value.title?.trim() : displayName;
351
+ const lastMessagePreview = preview(value.lastMessage);
352
+ const common = {
353
+ id,
354
+ title: title === void 0 || title.length === 0 ? required(value.kind === "direct" ? value.peerHandle ?? value.peerDid : value.groupDid) : title,
355
+ unreadCount: value.unreadCount,
356
+ ...value.lastMessageAt === void 0 ? {} : { lastMessageAt: timestamp(value.lastMessageAt) },
357
+ ...lastMessagePreview === void 0 ? {} : { lastMessagePreview }
358
+ };
359
+ if (value.lastMessage !== void 0 && displayableMessage(value.lastMessage)) this.message(value.lastMessage);
360
+ switch (value.kind) {
361
+ case "direct": return {
362
+ kind: "direct",
363
+ ...common,
364
+ peerDid: required(profile?.did ?? value.peerDid),
365
+ ...profileHandle === void 0 && value.peerHandle === void 0 ? {} : { peerHandle: required(profileHandle ?? value.peerHandle) },
366
+ ...displayName === void 0 || displayName.length === 0 ? {} : { displayName }
367
+ };
368
+ case "group": return {
369
+ kind: "group",
370
+ ...common,
371
+ groupDid: required(value.groupDid)
372
+ };
373
+ default: fail();
374
+ }
375
+ }
376
+ createdGroup(value) {
377
+ return {
378
+ kind: "group",
379
+ id: required(value.conversationId),
380
+ groupDid: required(value.did),
381
+ title: required(value.title),
382
+ unreadCount: 0
383
+ };
384
+ }
385
+ groupMember(value) {
386
+ return {
387
+ did: required(value.did),
388
+ ...value.handle === void 0 ? {} : { handle: value.handle }
389
+ };
390
+ }
391
+ listenerConversation(value) {
392
+ const common = {
393
+ id: required(value.id),
394
+ unreadCount: value.unreadCount,
395
+ ...value.lastMessageAt === void 0 ? {} : { lastMessageAt: timestamp(value.lastMessageAt) }
396
+ };
397
+ if (value.kind === "direct") return {
398
+ kind: "direct",
399
+ ...common,
400
+ peerDid: required(value.peerDid),
401
+ ...value.peerHandle === void 0 ? {} : { peerHandle: value.peerHandle }
402
+ };
403
+ return {
404
+ kind: "group",
405
+ ...common
406
+ };
407
+ }
408
+ listenerMessage(value) {
409
+ const sentAt = value.sentAt === void 0 ? fail() : timestamp(value.sentAt);
410
+ const common = {
411
+ id: required(value.id),
412
+ conversationId: required(value.conversationId),
413
+ conversationKind: value.conversationKind,
414
+ senderDid: required(value.senderDid),
415
+ sentAt,
416
+ outgoing: value.outgoing
417
+ };
418
+ return value.content.kind === "text" && value.content.text !== void 0 ? {
419
+ ...common,
420
+ content: {
421
+ kind: "text",
422
+ text: required(value.content.text)
423
+ }
424
+ } : {
425
+ ...common,
426
+ content: { kind: "ignored" }
427
+ };
428
+ }
429
+ listenerSyncNow(reason) {
430
+ return this.run(async (client) => {
431
+ const result = await client.syncNow({ reason });
432
+ if (result.status === "idle" || result.status === "changed") return;
433
+ if (result.status === "auth_revoked") fail("forbidden");
434
+ fail("network");
435
+ });
436
+ }
437
+ listenerStartRealtime() {
438
+ return this.run(async (client) => {
439
+ const session = await client.startRealtime();
440
+ return {
441
+ nextEvent: () => this.run(() => session.nextEvent()),
442
+ stop: () => this.run(() => session.stop())
443
+ };
444
+ });
445
+ }
446
+ listenerConversations(request) {
447
+ return this.run(async (client) => page(await client.listConversations(request), (value) => this.listenerConversation(value)));
448
+ }
449
+ listenerHistory(request) {
450
+ return this.run(async (client) => {
451
+ const history = await client.getHistory({
452
+ conversationId: String(request.conversationId),
453
+ ...request.cursor === void 0 ? {} : { cursor: String(request.cursor) },
454
+ ...request.limit === void 0 ? {} : { limit: request.limit }
455
+ });
456
+ return page({
457
+ ...history,
458
+ items: [...history.items].reverse()
459
+ }, (value) => this.listenerMessage(value));
460
+ });
461
+ }
462
+ async conversationId(client, target) {
463
+ if (target.kind === "direct") return required((await client.resolvePeer(target.peer)).conversationId);
464
+ let cursor;
465
+ for (let index = 0; index < MAX_GROUP_LOOKUP_PAGES; index += 1) {
466
+ const result = await client.listConversations({
467
+ ...cursor === void 0 ? {} : { cursor },
468
+ limit: GROUP_LOOKUP_LIMIT
469
+ });
470
+ const match = result.items.find((item) => item.kind === "group" && (item.id === target.group || item.groupDid === target.group));
471
+ if (match !== void 0) return required(match.id);
472
+ if (!result.hasMore || result.nextCursor === void 0) fail("not-found");
473
+ cursor = result.nextCursor;
474
+ }
475
+ fail("not-found");
476
+ }
477
+ prepareExternalHttpRequest(request) {
478
+ return this.run(async (client) => externalHttpAttempt(await client.prepareExternalHttpRequest({
479
+ url: request.url,
480
+ method: request.method,
481
+ headers: request.headers.map((header) => ({
482
+ name: header.name,
483
+ value: header.value
484
+ })),
485
+ ...request.body === void 0 ? {} : { body: Uint8Array.from(request.body) }
486
+ })));
487
+ }
488
+ getIdentity() {
489
+ return this.run(async (client) => {
490
+ const value = await client.getDefaultIdentity();
491
+ return value === null ? null : identity(value);
492
+ });
493
+ }
494
+ sendRegistrationOtp(request) {
495
+ return this.run(async (client) => {
496
+ const value = await client.requestRegistrationOtp(request);
497
+ return {
498
+ retryAfterSeconds: value.retryAfterSeconds,
499
+ retryAt: value.retryAt
500
+ };
501
+ });
502
+ }
503
+ registerIdentity(request) {
504
+ return this.run(async (client) => identity(await client.completeRegistration(request)));
505
+ }
506
+ updateDisplayName(request) {
507
+ return this.run(async (client) => identity(await client.updateDisplayName(request.displayName)));
508
+ }
509
+ resolvePeer(peer) {
510
+ return this.run(async (client) => {
511
+ const value = await client.resolvePeer(peer);
512
+ return {
513
+ did: required(value.did),
514
+ conversationId: required(value.conversationId),
515
+ ...value.handle === void 0 ? {} : { handle: value.handle },
516
+ ...value.displayName === void 0 ? {} : { displayName: value.displayName }
517
+ };
518
+ });
519
+ }
520
+ createGroup(name) {
521
+ return this.run(async (client) => this.createdGroup(await client.createGroup({ name })));
522
+ }
523
+ addGroupMember(groupDid, member) {
524
+ return this.run(async (client) => this.groupMember(await client.addGroupMember({
525
+ groupDid: String(groupDid),
526
+ member
527
+ })));
528
+ }
529
+ listConversations(request) {
530
+ return this.run(async (client) => {
531
+ const conversations = await client.listConversations(request);
532
+ return {
533
+ ...page(conversations, (value) => value),
534
+ items: await this.displayableConversations(client, conversations.items)
535
+ };
536
+ });
537
+ }
538
+ getHistory(request) {
539
+ return this.run(async (client) => {
540
+ const history = await client.getHistory({
541
+ conversationId: String(request.conversationId),
542
+ ...request.cursor === void 0 ? {} : { cursor: String(request.cursor) },
543
+ ...request.limit === void 0 ? {} : { limit: request.limit }
544
+ });
545
+ return page({
546
+ ...history,
547
+ items: await this.displayableMessages(client, [...history.items].reverse())
548
+ }, (value) => this.message(value));
549
+ });
550
+ }
551
+ getLocalHistory(request) {
552
+ return this.run(async (client) => {
553
+ const history = await client.getLocalConversationTimeline({
554
+ conversationId: String(request.conversationId),
555
+ ...request.cursor === void 0 ? {} : { cursor: String(request.cursor) },
556
+ ...request.limit === void 0 ? {} : { limit: request.limit }
557
+ });
558
+ return page({
559
+ ...history,
560
+ items: await this.displayableMessages(client, [...history.items].reverse())
561
+ }, (value) => this.message(value));
562
+ });
563
+ }
564
+ markConversationRead(conversationId) {
565
+ return this.run(async (client) => (await client.markConversationRead(String(conversationId))).updatedCount);
566
+ }
567
+ sendText(request) {
568
+ return this.run(async (client) => {
569
+ const clientMessageId = browserMessageId(request.idempotencyKey);
570
+ return this.message(await client.sendText({
571
+ conversationId: await this.conversationId(client, request.target),
572
+ text: request.text,
573
+ ...clientMessageId === void 0 ? {} : { clientMessageId },
574
+ idempotencyKey: request.idempotencyKey
575
+ }));
576
+ });
577
+ }
578
+ sendAttachment(request) {
579
+ return this.run(async (client) => {
580
+ const clientMessageId = browserMessageId(request.idempotencyKey);
581
+ return this.message(await client.sendAttachment({
582
+ conversationId: await this.conversationId(client, request.target),
583
+ fileName: request.attachment.fileName,
584
+ mimeType: request.attachment.mimeType,
585
+ bytes: request.attachment.bytes,
586
+ ...request.caption === void 0 ? {} : { caption: request.caption },
587
+ ...clientMessageId === void 0 ? {} : { clientMessageId },
588
+ idempotencyKey: request.idempotencyKey
589
+ }));
590
+ });
591
+ }
592
+ downloadAttachment(request) {
593
+ return this.run(async (client) => {
594
+ const conversationId = this.attachmentConversations.get(`${String(request.messageId)}\u0000${String(request.attachmentId)}`);
595
+ if (conversationId === void 0) fail("not-found");
596
+ const value = await client.downloadAttachment({
597
+ conversationId,
598
+ messageId: String(request.messageId),
599
+ attachmentId: String(request.attachmentId)
600
+ });
601
+ return {
602
+ attachment: attachment(value.attachment),
603
+ bytes: Uint8Array.from(value.bytes)
604
+ };
605
+ });
606
+ }
607
+ getMailAccount() {
608
+ return this.run(async (client) => mailAccount(await client.getMailAccount()));
609
+ }
610
+ listMailInbox(request = {}) {
611
+ return this.run(async (client) => mailInbox(await client.listMailInbox({
612
+ ...request.folder === void 0 ? {} : { folder: request.folder },
613
+ ...request.unreadOnly === void 0 ? {} : { unreadOnly: request.unreadOnly },
614
+ ...request.limit === void 0 ? {} : { limit: request.limit },
615
+ ...request.offset === void 0 ? {} : { offset: request.offset }
616
+ })));
617
+ }
618
+ readMail(request) {
619
+ return this.run(async (client) => mailMessage(await client.readMail(request.messageId)));
620
+ }
621
+ markMailRead(request) {
622
+ return this.run(async (client) => {
623
+ return { updated: uint32((await client.markMailRead({ messageIds: [...request.messageIds] })).updated) };
624
+ });
625
+ }
626
+ sendMail(request) {
627
+ return this.run(async (client) => {
628
+ const value = await client.sendMail({
629
+ to: [...request.to],
630
+ ...request.cc === void 0 ? {} : { cc: [...request.cc] },
631
+ subject: request.subject,
632
+ bodyText: request.bodyText
633
+ });
634
+ if (!Array.isArray(value.warnings) || value.warnings.length > 100) fail();
635
+ const messageId = value.messageId === void 0 ? void 0 : mailToken(value.messageId, 2048);
636
+ return {
637
+ accepted: boolean(value.accepted),
638
+ ...messageId === void 0 ? {} : { messageId },
639
+ warnings: value.warnings.map((warning) => remoteString(warning, 1024))
640
+ };
641
+ }, true);
642
+ }
643
+ clearLocalData() {
644
+ return this.run((client) => client.clearLocalData());
645
+ }
646
+ dispose() {
647
+ this.disposal ??= this.client.then(async (client) => {
648
+ try {
649
+ await client.close();
650
+ } catch (error) {
651
+ mapError(error);
652
+ }
653
+ }, () => void 0);
654
+ return this.disposal;
655
+ }
656
+ };
657
+ /**
658
+ * Convert a raw provider download to the Remote JSON representation.
659
+ * @param value - provider-verified public metadata and bytes.
660
+ * @returns detached metadata with canonical Base64 bytes.
661
+ */
662
+ function downloadedAttachment(value) {
663
+ return {
664
+ attachment: { ...value.attachment },
665
+ bytesBase64: Buffer.from(value.bytes).toString("base64")
666
+ };
667
+ }
668
+ //#endregion
669
+ export { downloadedAttachment as n, RustSdkAdapter as t };