@pmate/chat-sdk 0.12.0-next.14 → 0.12.0-next.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.
@@ -101,12 +101,13 @@ export declare class ChatSession<T extends StoredMessage> {
101
101
  /** Bridge transports can delegate social events without maintaining clients. */
102
102
  handleReach(event: OnlineReachEvent): Promise<"handled" | undefined>;
103
103
  private wakeCounts;
104
+ private publishCountSnapshot;
104
105
  private publishCounts;
105
106
  private watchCounts;
106
107
  getSnapshot(): ChatSummarySnapshot<T>;
107
108
  getSnapshot(threadId: string): ChatThreadSnapshot<T>;
108
109
  subscribe(listener: () => void): () => void;
109
- subscribe(threadId: string, listener: () => void): () => void;
110
+ subscribe(threadId: string, listener: () => void, fields?: readonly (keyof ChatThreadSnapshot<T>)[]): () => void;
110
111
  private publishAll;
111
112
  private buildGlobal;
112
113
  private publishGlobal;
@@ -257,6 +257,16 @@ export class ChatSession {
257
257
  if (this.counts && this.countsThread && !this.closed)
258
258
  this.countTasks.schedule("counts", async () => { this.counts?.reconnect(); });
259
259
  }
260
+ publishCountSnapshot(thread) {
261
+ const previous = this.snapshots.get(thread);
262
+ if (!previous) {
263
+ this.publish(thread, false);
264
+ return;
265
+ }
266
+ // Receipt-only updates never serialize or rebuild message bodies.
267
+ this.snapshots.set(thread, { ...previous, readCounts: this.countSnapshots.get(thread) });
268
+ this.listeners.get(thread)?.forEach(listener => listener());
269
+ }
260
270
  publishCounts(value) {
261
271
  const previous = this.countSnapshots.get(value.threadId);
262
272
  if ((previous && previous.revision > value.revision) || JSON.stringify(previous) === JSON.stringify(value))
@@ -266,9 +276,9 @@ export class ChatSession {
266
276
  if (this.countSnapshots.size > 128) {
267
277
  const oldest = this.countSnapshots.keys().next().value;
268
278
  this.countSnapshots.delete(oldest);
269
- this.publish(oldest, false);
279
+ this.publishCountSnapshot(oldest);
270
280
  }
271
- this.publish(value.threadId, false);
281
+ this.publishCountSnapshot(value.threadId);
272
282
  }
273
283
  watchCounts(threadId, ids, receiver = this.connection.identityScope().clientInstanceId) {
274
284
  if (!threadId || !ids.length) {
@@ -293,7 +303,7 @@ export class ChatSession {
293
303
  if (/READ_COUNTS_HTTP_(401|403)/.test(String(error))) {
294
304
  const threads = [...this.countSnapshots.keys()];
295
305
  this.countSnapshots.clear();
296
- threads.forEach(thread => this.publish(thread, false));
306
+ threads.forEach(thread => this.publishCountSnapshot(thread));
297
307
  }
298
308
  this.options.onError(error);
299
309
  } });
@@ -318,14 +328,23 @@ export class ChatSession {
318
328
  }
319
329
  return snapshot;
320
330
  }
321
- subscribe(target, listener) {
331
+ subscribe(target, listener, fields) {
322
332
  this.assertOpen();
323
333
  if (typeof target === "function") {
324
334
  this.globalListeners.add(target);
325
335
  return () => { this.globalListeners.delete(target); };
326
336
  }
327
337
  const threadId = target;
328
- const notify = listener;
338
+ const selected = fields ? [...fields] : undefined;
339
+ let values = selected?.map(field => this.getSnapshot(threadId)[field]);
340
+ const equal = (a, b) => a === b || (Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((value, index) => value === b[index]));
341
+ const notify = selected ? () => {
342
+ const next = selected.map(field => this.getSnapshot(threadId)[field]);
343
+ const changed = next.some((value, index) => !equal(value, values[index]));
344
+ values = next;
345
+ if (changed)
346
+ listener();
347
+ } : listener;
329
348
  let listeners = this.listeners.get(threadId);
330
349
  if (!listeners) {
331
350
  listeners = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/chat-sdk",
3
- "version": "0.12.0-next.14",
3
+ "version": "0.12.0-next.15",
4
4
  "description": "Cross-platform PMate chat input components, voice input primitives, and ASR helpers",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",