Skip to content

docs(chat-store): document the session-wide arrival feed - #515

Merged
jlucaso1 merged 3 commits into
mainfrom
claude/nifty-bohr-q2ww27
Aug 11, 2026
Merged

docs(chat-store): document the session-wide arrival feed#515
jlucaso1 merged 3 commits into
mainfrom
claude/nifty-bohr-q2ww27

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Documents the new session-wide arrival-ordered message API added in oxidezap/whatsapp-rust#1284:

  • ChatStore::messages_by_arrival / messages_by_arrival_in_range — a keyset-paginated feed over every chat interleaved by arrival order, for a reconciliation consumer that wants "everything that landed since I last looked" without an N+1 walk of the chat list.
  • The new ArrivalCursor type, and why it's a distinct type from MessageCursor (the two feeds sort by different keys).

Changes to api/chat-store.mdx

  • New "Querying" entry for messages_by_arrival/messages_by_arrival_in_range: paging contract (re-enter at the head, compare by (chat_jid, id), never stop at a remembered seq), why it orders by arrival instead of timestamp_ms (history-sync backfill lands old messages at new arrival positions), the tombstone/mutation boundary with subscribe(), and the wall-clock window's scan-cost caveat.
  • New ArrivalCursor entry under Types, next to MessageCursor.
  • A bullet in "Semantics worth knowing" noting the feed tracks insertion, not mutation.

Straight documentation of the new public API surface; no other behavior changed in this PR.


Generated by Claude Code


Summary by cubic

Documents the session-wide, arrival-ordered message feed and ArrivalCursor in chat-store, with clear paging and ordering rules. Shows how to pull everything that landed across all chats without N+1 per-thread paging.

  • New Features

    • Docs for messages_by_arrival / messages_by_arrival_in_range: newest-first, keyset-paginated by ArrivalCursor.
    • Paging and ordering: re-enter at head; order by seq (not timestamp_ms); ranged windows are half-open; compare by (chat_jid, id); limit <= 0 returns nothing.
  • Caveats

    • SQLite may reuse seq (rowid) after per-chat deletes (delete-for-me/clear-chat), so watermarking by seq can skip new arrivals.
    • Adjacent wall-clock windows only tile within a single scan; outgoing timestamp_ms can be corrected after insert and cross a window boundary.
    • chat_jid is not stable across PN/LID merges; normalize before (chat_jid, id) deduping to avoid misreading a rekeyed row as new.
    • Feed tracks insertions only; mutations don’t resurface; cursors aren’t durable across restarts.

Written for commit 742b1bd. Summary will update on new commits.

Covers messages_by_arrival/messages_by_arrival_in_range and the new
ArrivalCursor type: paging contract, why it orders by seq instead of
timestamp_ms, and the watermark pitfall the PR's tests pin (a deleted
message's seq can be reused by the next arrival).
@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
whatsapp-rust 🟢 Ready View Preview Aug 11, 2026, 9:47 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The ChatStore documentation adds session-wide arrival-ordered message feeds with optional half-open timestamp filters. It defines ArrivalCursor, updates StoredMessage.seq references, and documents insertion-order and mutation semantics.

Changes

Arrival-ordered message feeds

Layer / File(s) Summary
Arrival feed API and cursor semantics
api/chat-store.mdx
Documents the new arrival feed methods, ArrivalCursor, pagination behavior, timestamp filtering, and insertion-order semantics. Updates StoredMessage.seq documentation and explains that later mutations do not resurface messages.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Poem

A rabbit hops through messages in line,
With cursors that mark each arrival time.
Filters open a half-way gate,
While edits stay behind their date.
“Seq!” says the hare, “Keep feeds precise!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the documented session-wide arrival feed APIs and matches the pull request objectives.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/chat-store.mdx`:
- Around line 226-228: Update the new documentation sections around
messages_by_arrival and the related sections to address the reader directly in
second person and use active voice. Format all API and type references,
including messages_by_arrival, messages, MessageCursor, and ArrivalCursor, as
inline code; apply the same style to the additional referenced sections.
- Line 241: Qualify the `seq` reset statement in the saved-watermark
explanation: say it restarts at 1 only when clearing the chat empties the entire
table and the schema permits SQLite rowid reuse; otherwise, acknowledge that
rows from other chats can keep the sequence from resetting.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7cadfd25-0d84-4159-9e82-6d5f457edf1b

📥 Commits

Reviewing files that changed from the base of the PR and between c4bb104 and dc9e0e6.

📒 Files selected for processing (1)
  • api/chat-store.mdx

Comment thread api/chat-store.mdx Outdated
Comment thread api/chat-store.mdx Outdated
CodeRabbit correctly caught that clear-chat/delete-for-me delete rows
scoped to one chat, not the whole per-device messages table (verified
against ClearChatUpdate's delete_chat_rows call in store.rs) — so "restarts
at 1" only holds when that chat happened to hold every remaining row.
The general mechanism (freeing the table's max rowid for reuse) doesn't
depend on that special case, so it's what the watermark pitfall actually
rests on.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc9e0e6390

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread api/chat-store.mdx Outdated
}
```

Stopping at a saved watermark instead skips messages, silently. SQLite hands out the rowid backing `seq` as `max(rowid) + 1`, so deleting the newest message gives its number to the next arrival, and clearing a chat entirely restarts at 1 — both routine, since delete-for-me and clear-chat go through this store. A message that lands at or below a remembered `seq` after either reads as already seen and never surfaces again under a watermark comparison.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Qualify the rowid reset example

When any other chat still contains a message, clearing this chat does not restart seq at 1: SQLite chooses one more than the maximum rowid across the entire messages table. The reset occurs only when the operation empties that table, so qualify this as clearing the only remaining chat (or all messages) rather than presenting every routine clear-chat as a reset.

Useful? React with 👍 / 👎.

Comment thread api/chat-store.mdx Outdated
) -> Result<Vec<StoredMessage>>;
```

The session-wide feed: every chat interleaved, newest arrival first. This is the read a reconciliation consumer wants — "everything that landed since I last looked, across all chats" — which `chats` plus `messages` can otherwise only answer by paging every thread. `messages_by_arrival` is `messages_by_arrival_in_range` with no bounds; the ranged form additionally restricts the feed to a half-open wall-clock window, `since <= timestamp < until`, so adjacent windows tile without double-counting or dropping a row. Either bound may be `None`. A `limit` of zero, or negative (which SQLite reads as unbounded), returns nothing rather than the whole table.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Address the reader directly in the feed overview

The new overview describes what “a reconciliation consumer” wants instead of addressing the reader. Rewrite this as direct guidance such as “Use this read when you want…” so the section follows the repository’s required second-person voice.

AGENTS.md reference: AGENTS.md:L24-L24

Useful? React with 👍 / 👎.

Comment thread api/chat-store.mdx
Comment thread api/chat-store.mdx Outdated
Both verified against storages/chat-store/src:

- The wall-clock window's tiling guarantee ("adjacent windows tile
  without gaps/dupes") only holds for a single scan. store.rs's ack
  handler rewrites an outgoing row's timestamp_ms in place after insert,
  independent of seq, so a row can cross a window boundary between two
  queries taken at different times.
- The dedup loop's (chat_jid, id) comparison assumes chat_jid is stable.
  lid.rs's merge_split_chat does `UPDATE OR IGNORE messages SET chat_jid
  = ?` when healing a PN/LID split — its own comment notes rowids (seq)
  survive the update — so a message can reappear under a different
  chat_jid after a merge and get misread as new.

Also rephrased the feed's opening sentence to second person per this
repo's AGENTS.md style guideline, which Codex correctly cited.
@jlucaso1
jlucaso1 merged commit 658c724 into main Aug 11, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants