@astralform/js 9.5.0 → 9.6.0

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.
package/dist/index.cjs CHANGED
@@ -2825,6 +2825,48 @@ var ChatSession = class {
2825
2825
  if (!fresh.length) return;
2826
2826
  this.setMessages([...fresh, ...this.messages]);
2827
2827
  }
2828
+ /**
2829
+ * Re-fetch the NEWEST page of the conversation list and merge it in.
2830
+ *
2831
+ * The list the sidebar renders is seeded once at `connect()` and then only
2832
+ * changed by this client's own actions (create, delete, rename) — so a row's
2833
+ * `activeJobId` is as fresh as that seed, and a job started in ANOTHER tab or
2834
+ * on another device never appears, while one that ended elsewhere stays lit
2835
+ * forever. A caller that refreshes on a trigger (the tab becoming visible, or
2836
+ * a bounded interval while any job is live) keeps the rows honest without a
2837
+ * socket per conversation.
2838
+ *
2839
+ * Merge rules, and why each is what it is:
2840
+ *
2841
+ * - the server's ORDER wins for the rows it returns: an updated conversation
2842
+ * moves to its new place, which is the whole point of the call;
2843
+ * - rows paged in EARLIER (`loadMoreConversations`) are kept — this reads page
2844
+ * 1 only, and dropping the tail would make a refresh silently truncate a
2845
+ * list the reader has already scrolled;
2846
+ * - a row the caller MINTED locally and the server does not know yet is kept
2847
+ * too (it has no server row to be refreshed by);
2848
+ * - `conversationsGeneration` is bumped, for the same reason `connect()`
2849
+ * bumps it: a page request already in flight was cut against the old head
2850
+ * and its offset no longer means what it did.
2851
+ */
2852
+ async refreshConversations() {
2853
+ const page = await this.client.getConversations(CONVERSATION_PAGE_SIZE, 0);
2854
+ const pageIds = new Set(page.map((c) => c.id));
2855
+ const known = new Set(this.conversations.map((c) => c.id));
2856
+ this.conversationsGeneration++;
2857
+ this.conversations = [
2858
+ ...page,
2859
+ // Everything the page did not mention: older pages, and rows that exist
2860
+ // only on this client (a minted conversation the server has not been told
2861
+ // about yet).
2862
+ ...this.conversations.filter((c) => !pageIds.has(c.id))
2863
+ ];
2864
+ for (const c of page) {
2865
+ this.serverConversationIds.add(c.id);
2866
+ known.delete(c.id);
2867
+ }
2868
+ return page;
2869
+ }
2828
2870
  async loadMoreConversations() {
2829
2871
  if (this.isLoadingConversations || !this.hasMoreConversations) return [];
2830
2872
  this.isLoadingConversations = true;