@xmtp/browser-sdk 6.4.1 → 7.0.0-dev.57a7203

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.
@@ -10,6 +10,7 @@ import {
10
10
  type RemoteAttachment,
11
11
  type Reply,
12
12
  type SendMessageOpts,
13
+ type SendOpts,
13
14
  type TransactionReference,
14
15
  type WalletSendCalls,
15
16
  type DecodedMessage as XmtpDecodedMessage,
@@ -140,6 +141,19 @@ export class Conversation<ContentTypes = unknown> {
140
141
  });
141
142
  }
142
143
 
144
+ /**
145
+ * Decodes, decrypts, and persists a raw envelope from a group message stream.
146
+ *
147
+ * @param envelopeBytes - Raw protobuf-encoded envelope bytes from the stream
148
+ * @returns The processed and stored messages
149
+ */
150
+ async processStreamedMessage(envelopeBytes: Uint8Array) {
151
+ return this.#worker.action("conversation.processStreamedMessage", {
152
+ id: this.#id,
153
+ envelopeBytes,
154
+ });
155
+ }
156
+
143
157
  /**
144
158
  * Sends a message
145
159
  *
@@ -147,8 +161,10 @@ export class Conversation<ContentTypes = unknown> {
147
161
  * @param options - Optional send options
148
162
  * @param options.shouldPush - Indicates whether this message should be
149
163
  * included in push notifications
150
- * @param options.isOptimistic - Indicates whether this message should be
164
+ * @param options.optimistic - Indicates whether this message should be
151
165
  * sent optimistically and published later via `publishMessages`
166
+ * @param options.idempotencyKey - Optional idempotency key; re-sending
167
+ * identical content with the same key produces the same deduplicated message id
152
168
  * @returns Promise that resolves with the message ID after it has been sent
153
169
  */
154
170
  async send(content: EncodedContent, options?: SendMessageOpts) {
@@ -163,14 +179,14 @@ export class Conversation<ContentTypes = unknown> {
163
179
  * Sends a text message
164
180
  *
165
181
  * @param text - The text to send
166
- * @param isOptimistic - Whether to send the message optimistically
182
+ * @param opts - Send options (optimistic delivery, idempotency key)
167
183
  * @returns Promise that resolves with the message ID after it has been sent
168
184
  */
169
- async sendText(text: string, isOptimistic?: boolean) {
185
+ async sendText(text: string, opts?: SendOpts) {
170
186
  return this.#worker.action("conversation.sendText", {
171
187
  id: this.#id,
172
188
  text,
173
- isOptimistic,
189
+ opts,
174
190
  });
175
191
  }
176
192
 
@@ -178,14 +194,14 @@ export class Conversation<ContentTypes = unknown> {
178
194
  * Sends a markdown message
179
195
  *
180
196
  * @param markdown - The markdown to send
181
- * @param isOptimistic - Whether to send the message optimistically
197
+ * @param opts - Send options (optimistic delivery, idempotency key)
182
198
  * @returns Promise that resolves with the message ID after it has been sent
183
199
  */
184
- async sendMarkdown(markdown: string, isOptimistic?: boolean) {
200
+ async sendMarkdown(markdown: string, opts?: SendOpts) {
185
201
  return this.#worker.action("conversation.sendMarkdown", {
186
202
  id: this.#id,
187
203
  markdown,
188
- isOptimistic,
204
+ opts,
189
205
  });
190
206
  }
191
207
 
@@ -193,27 +209,27 @@ export class Conversation<ContentTypes = unknown> {
193
209
  * Sends a reaction message
194
210
  *
195
211
  * @param reaction - The reaction to send
196
- * @param isOptimistic - Whether to send the message optimistically
212
+ * @param opts - Send options (optimistic delivery, idempotency key)
197
213
  * @returns Promise that resolves with the message ID after it has been sent
198
214
  */
199
- async sendReaction(reaction: Reaction, isOptimistic?: boolean) {
215
+ async sendReaction(reaction: Reaction, opts?: SendOpts) {
200
216
  return this.#worker.action("conversation.sendReaction", {
201
217
  id: this.#id,
202
218
  reaction,
203
- isOptimistic,
219
+ opts,
204
220
  });
205
221
  }
206
222
 
207
223
  /**
208
224
  * Sends a read receipt message
209
225
  *
210
- * @param isOptimistic - Whether to send the message optimistically
226
+ * @param opts - Send options (optimistic delivery, idempotency key)
211
227
  * @returns Promise that resolves with the message ID after it has been sent
212
228
  */
213
- async sendReadReceipt(isOptimistic?: boolean) {
229
+ async sendReadReceipt(opts?: SendOpts) {
214
230
  return this.#worker.action("conversation.sendReadReceipt", {
215
231
  id: this.#id,
216
- isOptimistic,
232
+ opts,
217
233
  });
218
234
  }
219
235
 
@@ -221,14 +237,14 @@ export class Conversation<ContentTypes = unknown> {
221
237
  * Sends a reply message
222
238
  *
223
239
  * @param reply - The reply to send
224
- * @param isOptimistic - Whether to send the message optimistically
240
+ * @param opts - Send options (optimistic delivery, idempotency key)
225
241
  * @returns Promise that resolves with the message ID after it has been sent
226
242
  */
227
- async sendReply(reply: Reply, isOptimistic?: boolean) {
243
+ async sendReply(reply: Reply, opts?: SendOpts) {
228
244
  return this.#worker.action("conversation.sendReply", {
229
245
  id: this.#id,
230
246
  reply,
231
- isOptimistic,
247
+ opts,
232
248
  });
233
249
  }
234
250
 
@@ -236,17 +252,17 @@ export class Conversation<ContentTypes = unknown> {
236
252
  * Sends a transaction reference message
237
253
  *
238
254
  * @param transactionReference - The transaction reference to send
239
- * @param isOptimistic - Whether to send the message optimistically
255
+ * @param opts - Send options (optimistic delivery, idempotency key)
240
256
  * @returns Promise that resolves with the message ID after it has been sent
241
257
  */
242
258
  async sendTransactionReference(
243
259
  transactionReference: TransactionReference,
244
- isOptimistic?: boolean,
260
+ opts?: SendOpts,
245
261
  ) {
246
262
  return this.#worker.action("conversation.sendTransactionReference", {
247
263
  id: this.#id,
248
264
  transactionReference,
249
- isOptimistic,
265
+ opts,
250
266
  });
251
267
  }
252
268
 
@@ -254,17 +270,14 @@ export class Conversation<ContentTypes = unknown> {
254
270
  * Sends a wallet send calls message
255
271
  *
256
272
  * @param walletSendCalls - The wallet send calls to send
257
- * @param isOptimistic - Whether to send the message optimistically
273
+ * @param opts - Send options (optimistic delivery, idempotency key)
258
274
  * @returns Promise that resolves with the message ID after it has been sent
259
275
  */
260
- async sendWalletSendCalls(
261
- walletSendCalls: WalletSendCalls,
262
- isOptimistic?: boolean,
263
- ) {
276
+ async sendWalletSendCalls(walletSendCalls: WalletSendCalls, opts?: SendOpts) {
264
277
  return this.#worker.action("conversation.sendWalletSendCalls", {
265
278
  id: this.#id,
266
279
  walletSendCalls,
267
- isOptimistic,
280
+ opts,
268
281
  });
269
282
  }
270
283
 
@@ -272,14 +285,14 @@ export class Conversation<ContentTypes = unknown> {
272
285
  * Sends an actions message
273
286
  *
274
287
  * @param actions - The actions to send
275
- * @param isOptimistic - Whether to send the message optimistically
288
+ * @param opts - Send options (optimistic delivery, idempotency key)
276
289
  * @returns Promise that resolves with the message ID after it has been sent
277
290
  */
278
- async sendActions(actions: Actions, isOptimistic?: boolean) {
291
+ async sendActions(actions: Actions, opts?: SendOpts) {
279
292
  return this.#worker.action("conversation.sendActions", {
280
293
  id: this.#id,
281
294
  actions,
282
- isOptimistic,
295
+ opts,
283
296
  });
284
297
  }
285
298
 
@@ -287,14 +300,14 @@ export class Conversation<ContentTypes = unknown> {
287
300
  * Sends an intent message
288
301
  *
289
302
  * @param intent - The intent to send
290
- * @param isOptimistic - Whether to send the message optimistically
303
+ * @param opts - Send options (optimistic delivery, idempotency key)
291
304
  * @returns Promise that resolves with the message ID after it has been sent
292
305
  */
293
- async sendIntent(intent: Intent, isOptimistic?: boolean) {
306
+ async sendIntent(intent: Intent, opts?: SendOpts) {
294
307
  return this.#worker.action("conversation.sendIntent", {
295
308
  id: this.#id,
296
309
  intent,
297
- isOptimistic,
310
+ opts,
298
311
  });
299
312
  }
300
313
 
@@ -302,14 +315,14 @@ export class Conversation<ContentTypes = unknown> {
302
315
  * Sends an attachment message
303
316
  *
304
317
  * @param attachment - The attachment to send
305
- * @param isOptimistic - Whether to send the message optimistically
318
+ * @param opts - Send options (optimistic delivery, idempotency key)
306
319
  * @returns Promise that resolves with the message ID after it has been sent
307
320
  */
308
- async sendAttachment(attachment: Attachment, isOptimistic?: boolean) {
321
+ async sendAttachment(attachment: Attachment, opts?: SendOpts) {
309
322
  return this.#worker.action("conversation.sendAttachment", {
310
323
  id: this.#id,
311
324
  attachment,
312
- isOptimistic,
325
+ opts,
313
326
  });
314
327
  }
315
328
 
@@ -317,17 +330,17 @@ export class Conversation<ContentTypes = unknown> {
317
330
  * Sends a multi remote attachment message
318
331
  *
319
332
  * @param multiRemoteAttachment - The multi remote attachment to send
320
- * @param isOptimistic - Whether to send the message optimistically
333
+ * @param opts - Send options (optimistic delivery, idempotency key)
321
334
  * @returns Promise that resolves with the message ID after it has been sent
322
335
  */
323
336
  async sendMultiRemoteAttachment(
324
337
  multiRemoteAttachment: MultiRemoteAttachment,
325
- isOptimistic?: boolean,
338
+ opts?: SendOpts,
326
339
  ) {
327
340
  return this.#worker.action("conversation.sendMultiRemoteAttachment", {
328
341
  id: this.#id,
329
342
  multiRemoteAttachment,
330
- isOptimistic,
343
+ opts,
331
344
  });
332
345
  }
333
346
 
@@ -335,17 +348,17 @@ export class Conversation<ContentTypes = unknown> {
335
348
  * Sends a remote attachment message
336
349
  *
337
350
  * @param remoteAttachment - The remote attachment to send
338
- * @param isOptimistic - Whether to send the message optimistically
351
+ * @param opts - Send options (optimistic delivery, idempotency key)
339
352
  * @returns Promise that resolves with the message ID after it has been sent
340
353
  */
341
354
  async sendRemoteAttachment(
342
355
  remoteAttachment: RemoteAttachment,
343
- isOptimistic?: boolean,
356
+ opts?: SendOpts,
344
357
  ) {
345
358
  return this.#worker.action("conversation.sendRemoteAttachment", {
346
359
  id: this.#id,
347
360
  remoteAttachment,
348
- isOptimistic,
361
+ opts,
349
362
  });
350
363
  }
351
364
 
@@ -1,12 +1,19 @@
1
1
  import {
2
2
  verifySignedWithPublicKey,
3
+ type ArchiveMetadata,
3
4
  type ArchiveOptions,
5
+ type AvailableArchiveInfo,
4
6
  type Client,
7
+ type GroupSyncSummary,
5
8
  type Identifier,
6
9
  type KeyPackageStatus,
7
10
  type SignatureRequestHandle,
8
11
  } from "@xmtp/wasm-bindings";
9
- import type { ClientOptions, XmtpEnv } from "@/types/options";
12
+ import type {
13
+ ClientOptions,
14
+ VisibilityConfirmationOptions,
15
+ XmtpEnv,
16
+ } from "@/types/options";
10
17
  import { createClient } from "@/utils/createClient";
11
18
  import type { SafeSigner } from "@/utils/signer";
12
19
  import { WorkerConversations } from "@/WorkerConversations";
@@ -87,6 +94,19 @@ export class WorkerClient {
87
94
  >;
88
95
  }
89
96
 
97
+ async fetchLatestInboxUpdatesCount(inboxIds: string[]) {
98
+ const result = (await this.#client.fetchLatestInboxUpdatesCount(
99
+ true,
100
+ inboxIds,
101
+ )) as Map<string, number> | Record<string, number>;
102
+
103
+ return result instanceof Map ? Object.fromEntries(result) : result;
104
+ }
105
+
106
+ async fetchOwnInboxUpdatesCount() {
107
+ return this.#client.fetchOwnInboxUpdatesCount(true);
108
+ }
109
+
90
110
  async addSignature(
91
111
  signatureRequest: SignatureRequestHandle,
92
112
  signer: SafeSigner,
@@ -145,9 +165,13 @@ export class WorkerClient {
145
165
  async registerIdentity(
146
166
  signer: SafeSigner,
147
167
  signatureRequest: SignatureRequestHandle,
168
+ visibilityConfirmationOptions?: VisibilityConfirmationOptions,
148
169
  ) {
149
170
  await this.addSignature(signatureRequest, signer);
150
- await this.#client.registerIdentity(signatureRequest);
171
+ await this.#client.registerIdentity(
172
+ signatureRequest,
173
+ visibilityConfirmationOptions,
174
+ );
151
175
  }
152
176
 
153
177
  async getInboxIdByIdentifier(identifier: Identifier) {
@@ -195,4 +219,42 @@ export class WorkerClient {
195
219
  async sendSyncRequest(options: ArchiveOptions, serverUrl: string) {
196
220
  return this.#client.device_sync().sendSyncRequest(options, serverUrl);
197
221
  }
222
+
223
+ async sendSyncArchive(
224
+ options: ArchiveOptions,
225
+ serverUrl: string,
226
+ pin: string,
227
+ ) {
228
+ return this.#client.device_sync().sendSyncArchive(options, serverUrl, pin);
229
+ }
230
+
231
+ async processSyncArchive(archivePin?: string | null) {
232
+ return this.#client.device_sync().processSyncArchive(archivePin);
233
+ }
234
+
235
+ listAvailableArchives(daysCutoff: number): AvailableArchiveInfo[] {
236
+ return this.#client.device_sync().listAvailableArchives(BigInt(daysCutoff));
237
+ }
238
+
239
+ async createArchive(
240
+ opts: ArchiveOptions,
241
+ key: Uint8Array,
242
+ ): Promise<Uint8Array> {
243
+ return this.#client.device_sync().createArchive(opts, key);
244
+ }
245
+
246
+ async importArchive(data: Uint8Array, key: Uint8Array) {
247
+ return this.#client.device_sync().importArchive(data, key);
248
+ }
249
+
250
+ async archiveMetadata(
251
+ data: Uint8Array,
252
+ key: Uint8Array,
253
+ ): Promise<ArchiveMetadata> {
254
+ return this.#client.device_sync().archiveMetadata(data, key);
255
+ }
256
+
257
+ async syncAllDeviceSyncGroups(): Promise<GroupSyncSummary> {
258
+ return this.#client.device_sync().syncAllDeviceSyncGroups();
259
+ }
198
260
  }
@@ -23,6 +23,7 @@ import {
23
23
  type RemoteAttachment,
24
24
  type Reply,
25
25
  type SendMessageOpts,
26
+ type SendOpts,
26
27
  type TransactionReference,
27
28
  type WalletSendCalls,
28
29
  } from "@xmtp/wasm-bindings";
@@ -188,74 +189,69 @@ export class WorkerConversation {
188
189
  return this.#group.publishMessages();
189
190
  }
190
191
 
192
+ async processStreamedMessage(envelopeBytes: Uint8Array) {
193
+ return this.#group.processStreamedGroupMessage(envelopeBytes);
194
+ }
195
+
191
196
  async send(encodedContent: EncodedContent, opts?: SendMessageOpts) {
192
197
  return this.#group.send(encodedContent, opts ?? { shouldPush: true });
193
198
  }
194
199
 
195
- async sendText(text: string, isOptimistic?: boolean) {
196
- return this.#group.sendText(text, isOptimistic);
200
+ async sendText(text: string, opts?: SendOpts) {
201
+ return this.#group.sendText(text, opts);
197
202
  }
198
203
 
199
- async sendMarkdown(markdown: string, isOptimistic?: boolean) {
200
- return this.#group.sendMarkdown(markdown, isOptimistic);
204
+ async sendMarkdown(markdown: string, opts?: SendOpts) {
205
+ return this.#group.sendMarkdown(markdown, opts);
201
206
  }
202
207
 
203
- async sendReaction(reaction: Reaction, isOptimistic?: boolean) {
204
- return this.#group.sendReaction(reaction, isOptimistic);
208
+ async sendReaction(reaction: Reaction, opts?: SendOpts) {
209
+ return this.#group.sendReaction(reaction, opts);
205
210
  }
206
211
 
207
- async sendReadReceipt(isOptimistic?: boolean) {
208
- return this.#group.sendReadReceipt(isOptimistic);
212
+ async sendReadReceipt(opts?: SendOpts) {
213
+ return this.#group.sendReadReceipt(opts);
209
214
  }
210
215
 
211
- async sendReply(reply: Reply, isOptimistic?: boolean) {
212
- return this.#group.sendReply(reply, isOptimistic);
216
+ async sendReply(reply: Reply, opts?: SendOpts) {
217
+ return this.#group.sendReply(reply, opts);
213
218
  }
214
219
 
215
220
  async sendTransactionReference(
216
221
  transactionReference: TransactionReference,
217
- isOptimistic?: boolean,
222
+ opts?: SendOpts,
218
223
  ) {
219
- return this.#group.sendTransactionReference(
220
- transactionReference,
221
- isOptimistic,
222
- );
224
+ return this.#group.sendTransactionReference(transactionReference, opts);
223
225
  }
224
226
 
225
- async sendWalletSendCalls(
226
- walletSendCalls: WalletSendCalls,
227
- isOptimistic?: boolean,
228
- ) {
229
- return this.#group.sendWalletSendCalls(walletSendCalls, isOptimistic);
227
+ async sendWalletSendCalls(walletSendCalls: WalletSendCalls, opts?: SendOpts) {
228
+ return this.#group.sendWalletSendCalls(walletSendCalls, opts);
230
229
  }
231
230
 
232
- async sendActions(actions: Actions, isOptimistic?: boolean) {
233
- return this.#group.sendActions(actions, isOptimistic);
231
+ async sendActions(actions: Actions, opts?: SendOpts) {
232
+ return this.#group.sendActions(actions, opts);
234
233
  }
235
234
 
236
- async sendIntent(intent: Intent, isOptimistic?: boolean) {
237
- return this.#group.sendIntent(intent, isOptimistic);
235
+ async sendIntent(intent: Intent, opts?: SendOpts) {
236
+ return this.#group.sendIntent(intent, opts);
238
237
  }
239
238
 
240
- async sendAttachment(attachment: Attachment, isOptimistic?: boolean) {
241
- return this.#group.sendAttachment(attachment, isOptimistic);
239
+ async sendAttachment(attachment: Attachment, opts?: SendOpts) {
240
+ return this.#group.sendAttachment(attachment, opts);
242
241
  }
243
242
 
244
243
  async sendMultiRemoteAttachment(
245
244
  multiRemoteAttachment: MultiRemoteAttachment,
246
- isOptimistic?: boolean,
245
+ opts?: SendOpts,
247
246
  ) {
248
- return this.#group.sendMultiRemoteAttachment(
249
- multiRemoteAttachment,
250
- isOptimistic,
251
- );
247
+ return this.#group.sendMultiRemoteAttachment(multiRemoteAttachment, opts);
252
248
  }
253
249
 
254
250
  async sendRemoteAttachment(
255
251
  remoteAttachment: RemoteAttachment,
256
- isOptimistic?: boolean,
252
+ opts?: SendOpts,
257
253
  ) {
258
- return this.#group.sendRemoteAttachment(remoteAttachment, isOptimistic);
254
+ return this.#group.sendRemoteAttachment(remoteAttachment, opts);
259
255
  }
260
256
 
261
257
  async messages(options?: ListMessagesOptions): Promise<DecodedMessage[]> {
package/src/index.ts CHANGED
@@ -17,8 +17,10 @@ export type {
17
17
  Action,
18
18
  Actions,
19
19
  ApiStats,
20
+ ArchiveMetadata,
20
21
  ArchiveOptions,
21
22
  Attachment,
23
+ AvailableArchiveInfo,
22
24
  Backend,
23
25
  BackendBuilder,
24
26
  Consent,
@@ -56,12 +58,15 @@ export type {
56
58
  RemoteAttachment,
57
59
  Reply,
58
60
  SendMessageOpts,
61
+ SendOpts,
59
62
  SignatureRequestHandle,
60
63
  TransactionMetadata,
61
64
  TransactionReference,
62
65
  UserPreferenceUpdate,
63
66
  WalletCall,
64
67
  WalletSendCalls,
68
+ WorkerConfigOptions,
69
+ WorkerIntervalOverride,
65
70
  } from "@xmtp/wasm-bindings";
66
71
  export {
67
72
  ActionStyle,
@@ -85,6 +90,7 @@ export {
85
90
  ReactionAction,
86
91
  ReactionSchema,
87
92
  SortDirection,
93
+ WorkerKind,
88
94
  } from "@xmtp/wasm-bindings";
89
95
  export * from "./utils/signer";
90
96
  export * from "./utils/errors";
@@ -1,9 +1,15 @@
1
1
  import type {
2
+ ArchiveMetadata,
2
3
  ArchiveOptions,
4
+ AvailableArchiveInfo,
5
+ GroupSyncSummary,
3
6
  Identifier,
4
7
  KeyPackageStatus,
5
8
  } from "@xmtp/wasm-bindings";
6
- import type { ClientOptions } from "@/types/options";
9
+ import type {
10
+ ClientOptions,
11
+ VisibilityConfirmationOptions,
12
+ } from "@/types/options";
7
13
  import type { SafeSigner } from "@/utils/signer";
8
14
 
9
15
  export type ClientAction =
@@ -109,6 +115,7 @@ export type ClientAction =
109
115
  data: {
110
116
  signer: SafeSigner;
111
117
  signatureRequestId: string;
118
+ waitForRegistrationVisible?: VisibilityConfirmationOptions;
112
119
  };
113
120
  }
114
121
  | {
@@ -174,6 +181,20 @@ export type ClientAction =
174
181
  identifiers: Identifier[];
175
182
  };
176
183
  }
184
+ | {
185
+ action: "client.fetchLatestInboxUpdatesCount";
186
+ id: string;
187
+ result: Record<string, number>;
188
+ data: {
189
+ inboxIds: string[];
190
+ };
191
+ }
192
+ | {
193
+ action: "client.fetchOwnInboxUpdatesCount";
194
+ id: string;
195
+ result: number;
196
+ data: Record<string, never>;
197
+ }
177
198
  | {
178
199
  action: "client.getInboxIdByIdentifier";
179
200
  id: string;
@@ -225,4 +246,63 @@ export type ClientAction =
225
246
  options: ArchiveOptions;
226
247
  serverUrl: string;
227
248
  };
249
+ }
250
+ | {
251
+ action: "client.sendSyncArchive";
252
+ id: string;
253
+ result: undefined;
254
+ data: {
255
+ options: ArchiveOptions;
256
+ serverUrl: string;
257
+ pin: string;
258
+ };
259
+ }
260
+ | {
261
+ action: "client.processSyncArchive";
262
+ id: string;
263
+ result: undefined;
264
+ data: {
265
+ archivePin?: string | null;
266
+ };
267
+ }
268
+ | {
269
+ action: "client.listAvailableArchives";
270
+ id: string;
271
+ result: AvailableArchiveInfo[];
272
+ data: {
273
+ daysCutoff: number;
274
+ };
275
+ }
276
+ | {
277
+ action: "client.createArchive";
278
+ id: string;
279
+ result: Uint8Array;
280
+ data: {
281
+ opts: ArchiveOptions;
282
+ key: Uint8Array;
283
+ };
284
+ }
285
+ | {
286
+ action: "client.importArchive";
287
+ id: string;
288
+ result: undefined;
289
+ data: {
290
+ data: Uint8Array;
291
+ key: Uint8Array;
292
+ };
293
+ }
294
+ | {
295
+ action: "client.archiveMetadata";
296
+ id: string;
297
+ result: ArchiveMetadata;
298
+ data: {
299
+ data: Uint8Array;
300
+ key: Uint8Array;
301
+ };
302
+ }
303
+ | {
304
+ action: "client.syncAllDeviceSyncGroups";
305
+ id: string;
306
+ result: GroupSyncSummary;
307
+ data: undefined;
228
308
  };