Skip to content

fix(accounts): deeply compact stored account comments#46

Merged
tomcasaburi merged 2 commits intomasterfrom
fix/account-history-deep-compaction
Mar 20, 2026
Merged

fix(accounts): deeply compact stored account comments#46
tomcasaburi merged 2 commits intomasterfrom
fix/account-history-deep-compaction

Conversation

@tomcasaburi
Copy link
Member

@tomcasaburi tomcasaburi commented Mar 20, 2026

Deepens account comment compaction for existing users by rewriting legacy stored comments without runtime transport payloads, while keeping full history and first-party app behavior intact.

Closes #45


Note

Medium Risk
Touches comment persistence and IndexedDB migration logic; mistakes could drop or reorder users’ stored comment history even though tests cover common legacy scenarios.

Overview
Account comments are now compacted more aggressively in storage: sanitizeStoredAccountComment drops runtime-only fields (e.g. clients, raw, replies.pages) and stores an original snapshot only for edited comments (in a reduced, renderable form).

Live pending-comment state is preserved by introducing sanitizeAccountCommentForState (keeps renderable fields while dropping heavy payloads) and by snapshotting comment.clients into a state-safe shape during publishing so gateway/provider state updates don’t break pending comments.

IndexedDB comment storage migrates to v2: ensureAccountCommentsDatabaseLayout rewrites legacy entries through the new sanitizer, removes sparse/undefined slots, and updates length accordingly; tests expand coverage for export/read/delete migration and sparse-slot densification.

Written by Cursor Bugbot for commit 3cdb706. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • Tests

    • Expanded coverage for comment sanitization, storage compaction, client snapshot behavior, and migration/denser-index scenarios.
  • Refactor

    • Separated live/in-memory and persisted comment representations to avoid storing runtime-only fields.
    • Improved comment compaction to strip nested runtime payloads and preserve renderable comment data.
  • Chores

    • Bumped comment storage version and tightened migration to compact legacy data.

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

Introduces dual sanitization for comments (live vs persisted), snapshots client runtime state for in-memory entries, and migrates stored account comments by bumping storage version to compact and remove runtime payloads.

Changes

Cohort / File(s) Summary
Storage Versioning & Migration
src/stores/accounts/accounts-database.ts, src/stores/accounts/accounts-database.test.ts
Bumped comment storage version to 2. Migration now compacts legacy comment arrays, drops entries that sanitize to undefined, removes trailing slots, and updates "__storageVersion". Tests updated to expect removal of runtime fields and compaction behavior.
Comment Sanitization Utilities
src/stores/accounts/utils.ts, src/stores/accounts/utils.test.ts
Added sanitizeAccountCommentForState (for in-memory) and reworked sanitizeStoredAccountComment to compact replies/original, strip runtime-only fields (clients, raw, signer, replies.pages/clients) and remove empty containers. Tests added/expanded to validate both behaviors and original snapshot compaction.
Publish Flow & Client Snapshots
src/stores/accounts/accounts-actions.ts, src/stores/accounts/accounts-actions.test.ts
Added getClientsSnapshotForState and syncCommentClientsSnapshot. publishComment now writes a persisted sanitized variant to DB and a separate live sanitized variant to state; client state updates use compacted snapshots. Tests adjusted to reflect live-state expectations (e.g., content === "ipfs" remains after connect).

Sequence Diagram(s)

sequenceDiagram
  participant UI as Client/UI
  participant Actions as accounts-actions
  participant DB as Accounts DB
  participant State as In-Memory Store
  participant IPFS as IPFS Client

  UI->>Actions: publishComment(payload)
  Actions->>Actions: sanitizeStoredAccountComment -> persistedComment
  Actions->>DB: write persistedComment (storage)
  Actions->>Actions: sanitizeAccountCommentForState -> liveComment
  Actions->>State: insert/update liveComment (in-memory)
  Note over State,IPFS: IPFS client later emits statechange
  IPFS->>Actions: clientsOnStateChange(state)
  Actions->>Actions: getClientsSnapshotForState(...) -> clientsSnapshot
  Actions->>State: syncCommentClientsSnapshot(publishSessionId, accountId, clientsSnapshot)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

🐰 I nudge the payload light and neat,
Two paths for words—one safe, one fleet,
Old client crumbs and raw bits fade,
State stays spry, the store is made,
Hooray—my hop keeps data sweet! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(accounts): deeply compact stored account comments' clearly and specifically describes the main change—a fix that compacts stored account comments with deeper payload removal.
Linked Issues check ✅ Passed The PR fully addresses issue #45: removes runtime payloads (raw, clients, replies.pages/clients), rewrites legacy comments on upgrade via storage version bump, and preserves comment history while applying compaction.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue #45 objective of removing runtime transport data from stored comments and migrating legacy data without introducing unrelated functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/account-history-deep-compaction
📝 Coding Plan
  • Generate coding plan for human review comments

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

Tip

CodeRabbit can use OpenGrep to find security vulnerabilities and bugs across 17+ programming languages.

OpenGrep is compatible with Semgrep configurations. Add an opengrep.yml or semgrep.yml configuration file to your project to enable OpenGrep analysis.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/stores/accounts/accounts-actions.test.ts (1)

2121-2146: ⚠️ Potential issue | 🟡 Minor

Keep asserting the live clients snapshot here.

This test now only checks that the comment still exists. That misses the new behavior added in accounts-actions.ts: the store should keep a state-only clients snapshot and update it on "statechange". A regression in that path would still pass as long as the pending comment stays in the array, so please keep an assertion on clients.ipfsGateways["https://ipfs.io"].state.

Suggested assertion
       await new Promise((r) => setTimeout(r, 100));
       const comments = accountsStore.getState().accountsComments[account.id] || [];
-      expect(comments.find((c: any) => c.content === "ipfs")).toBeDefined();
+      const ipfsComment = comments.find((c: any) => c.content === "ipfs");
+      expect(ipfsComment).toBeDefined();
+      expect(ipfsComment?.clients).toEqual(
+        expect.objectContaining({
+          ipfsGateways: {
+            "https://ipfs.io": { state: "connected" },
+          },
+        }),
+      );
     });

As per coding guidelines When changing hooks or stores, consider whether existing tests cover the change; if not, add a test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stores/accounts/accounts-actions.test.ts` around lines 2121 - 2146, The
test currently only asserts the comment exists but must also assert the store's
state-only clients snapshot updates on "statechange"; after locating the newly
published comment in accountsStore.getState().accountsComments[account.id]
(e.g., find by content "ipfs"), assert that
comment.clients.ipfsGateways["https://ipfs.io"].state === "connected" (or the
expected state string) to cover the behavior added in
accounts-actions.publishComment that listens for client "statechange" and
updates the snapshot.
src/stores/accounts/accounts-database.ts (1)

378-389: ⚠️ Potential issue | 🟠 Major

Compact or drop sparse legacy comment slots before stamping v2.

getDatabaseAsArray() returns undefined for missing numeric keys, and this migration currently preserves those gaps while still writing __storageVersion = 2. getAccountComments() later assumes every slot is an object and dereferences comments[i].index, so a sparse or partially-written legacy accountComments DB will still fail as soon as the account is hydrated or exported. Please densify the array here, or skip falsy rows and rewrite length during the migration.

Suggested hardening
-      const comments = await getDatabaseAsArray(accountCommentsDatabase);
-      const updatedComments = comments.map((comment) =>
-        comment ? sanitizeStoredAccountComment(comment) : comment,
-      );
+      const comments = await getDatabaseAsArray(accountCommentsDatabase);
+      const updatedComments = comments
+        .map((comment) => (comment ? sanitizeStoredAccountComment(comment) : undefined))
+        .filter((comment) => comment !== undefined);
       const rewritePromises: Promise<void>[] = [];
       for (const [index, updatedComment] of updatedComments.entries()) {
         if (!isEqual(updatedComment, comments[index])) {
           rewritePromises.push(accountCommentsDatabase.setItem(String(index), updatedComment));
         }
       }
+      for (let index = updatedComments.length; index < comments.length; index++) {
+        rewritePromises.push(accountCommentsDatabase.removeItem(String(index)));
+      }
+      rewritePromises.push(accountCommentsDatabase.setItem("length", updatedComments.length));
       await Promise.all(rewritePromises);
       await accountCommentsDatabase.setItem(storageVersionKey, commentStorageVersion);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stores/accounts/accounts-database.ts` around lines 378 - 389, The
migration preserves sparse numeric keys (undefined slots) causing downstream
code (getAccountComments) to crash; instead build a dense array by filtering out
falsy entries from updatedComments, then rewrite accountCommentsDatabase with
contiguous numeric keys 0..N-1 (optionally setting each comment.index = i before
writing) — e.g., compute const dense = updatedComments.filter(Boolean), clear or
remove old numeric keys, write dense items back with
accountCommentsDatabase.setItem(String(i), dense[i]) for each i, and finally set
storageVersionKey to commentStorageVersion. Ensure you reference
getDatabaseAsArray, sanitizeStoredAccountComment, accountCommentsDatabase,
storageVersionKey, and commentStorageVersion when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/stores/accounts/accounts-actions.ts`:
- Around line 1039-1047: Extract the client-snapshot update logic (currently
using getPublishSession(publishSessionId),
getClientsSnapshotForState(comment?.clients) and accountsStore.setState(...)
with maybeUpdateAccountComment) into a helper like
syncCommentClientsSnapshot(publishSessionId, account, comment) that computes the
snapshot and updates accountsComments (including setting undefined to clear the
previous snapshot). Replace the inline block in the original path with a call to
this helper, and invoke the same helper immediately after any retry that
reassigns `comment` (the branch that handles failed challenge verification) so
the live `clients` snapshot is refreshed or cleared on every
createComment()/retry.

---

Outside diff comments:
In `@src/stores/accounts/accounts-actions.test.ts`:
- Around line 2121-2146: The test currently only asserts the comment exists but
must also assert the store's state-only clients snapshot updates on
"statechange"; after locating the newly published comment in
accountsStore.getState().accountsComments[account.id] (e.g., find by content
"ipfs"), assert that comment.clients.ipfsGateways["https://ipfs.io"].state ===
"connected" (or the expected state string) to cover the behavior added in
accounts-actions.publishComment that listens for client "statechange" and
updates the snapshot.

In `@src/stores/accounts/accounts-database.ts`:
- Around line 378-389: The migration preserves sparse numeric keys (undefined
slots) causing downstream code (getAccountComments) to crash; instead build a
dense array by filtering out falsy entries from updatedComments, then rewrite
accountCommentsDatabase with contiguous numeric keys 0..N-1 (optionally setting
each comment.index = i before writing) — e.g., compute const dense =
updatedComments.filter(Boolean), clear or remove old numeric keys, write dense
items back with accountCommentsDatabase.setItem(String(i), dense[i]) for each i,
and finally set storageVersionKey to commentStorageVersion. Ensure you reference
getDatabaseAsArray, sanitizeStoredAccountComment, accountCommentsDatabase,
storageVersionKey, and commentStorageVersion when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f1205d6c-a729-4060-9ddf-9604b1a59791

📥 Commits

Reviewing files that changed from the base of the PR and between d3d5db9 and d27c43e.

📒 Files selected for processing (6)
  • src/stores/accounts/accounts-actions.test.ts
  • src/stores/accounts/accounts-actions.ts
  • src/stores/accounts/accounts-database.test.ts
  • src/stores/accounts/accounts-database.ts
  • src/stores/accounts/utils.test.ts
  • src/stores/accounts/utils.ts

@tomcasaburi
Copy link
Member Author

Addressed the valid review findings in the latest commit. Fixed the sparse legacy accountComments migration by densifying and rewriting the numeric slots before stamping v2, and moved the live clients snapshot sync into a helper that also refreshes or clears the snapshot after retry-created publications. I did not keep the suggested final-state test assertion on comment.clients because successful publishes intentionally clear transport clients from settled account comments; that suggestion would assert the wrong behavior.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/stores/accounts/accounts-actions.ts (2)

62-78: Add brief documentation explaining the expected clients structure.

The recursive heuristic at line 66 treats any object with 'state' in clients as a leaf node. This works for the current structure but could behave unexpectedly if a nested container ever gains a state property.

Consider adding a brief JSDoc explaining the expected hierarchy (e.g., clients.ipfsGateways["url"].state) so future maintainers understand the termination condition.

📝 Suggested documentation
+/**
+ * Extracts a minimal snapshot of the `clients` hierarchy, preserving only
+ * `{ state }` for each transport client (leaf nodes detected by `.on` method
+ * or presence of a `state` property). Returns `undefined` when empty.
+ */
 const getClientsSnapshotForState = (clients: any): any => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stores/accounts/accounts-actions.ts` around lines 62 - 78, Add a short
JSDoc above the getClientsSnapshotForState function that documents the expected
shape of the clients input (a nested object tree whose leaves are client objects
containing a state property, e.g., clients.ipfsGateways["url"].state) and
explain the termination heuristic (treat any object with a "state" property or
an event-emitter-like "on" method as a leaf). This clarifies why the function
checks typeof clients.on === "function" || "state" in clients and warns
maintainers that adding a plain "state" property to a non-leaf container will
change behavior.

1104-1127: Consider extracting common property deletions to reduce duplication.

Both persistedCommentWithCid and liveCommentWithCid have the same four properties deleted (lines 1110-1117). While the dual sanitization is intentional (persisted strips clients via sanitizer, live preserves it but then explicitly removes it since CID receipt means publishing is complete), the repeated deletions could be DRYer.

♻️ Optional consolidation
           const persistedCommentWithCid = addShortAddressesToAccountComment(
             sanitizeStoredAccountComment(normalizePublicationOptionsForStore(comment as any)),
-          );
+          ) as any;
           const liveCommentWithCid = addShortAddressesToAccountComment(
             sanitizeAccountCommentForState(normalizePublicationOptionsForStore(comment as any)),
-          );
-          delete (persistedCommentWithCid as any).clients;
-          delete (persistedCommentWithCid as any).publishingState;
-          delete (persistedCommentWithCid as any).error;
-          delete (persistedCommentWithCid as any).errors;
-          delete (liveCommentWithCid as any).clients;
-          delete (liveCommentWithCid as any).publishingState;
-          delete (liveCommentWithCid as any).error;
-          delete (liveCommentWithCid as any).errors;
+          ) as any;
+          for (const obj of [persistedCommentWithCid, liveCommentWithCid]) {
+            delete obj.clients;
+            delete obj.publishingState;
+            delete obj.error;
+            delete obj.errors;
+          }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stores/accounts/accounts-actions.ts` around lines 1104 - 1127, Extract
the repeated deletions into a small helper (e.g., stripTransientCommentFields)
and call it for both persistedCommentWithCid and liveCommentWithCid instead of
repeating delete lines; locate where persistedCommentWithCid and
liveCommentWithCid are created (after
addShortAddressesToAccountComment/sanitizeStoredAccountComment and
sanitizeAccountCommentForState) and replace the eight delete statements with two
calls to that helper, ensuring it removes clients, publishingState, error, and
errors before calling accountsDatabase.addAccountComment and before building
updatedAccountComment for accountsStore.setState.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/stores/accounts/accounts-actions.ts`:
- Around line 62-102: Add assertions in the three publishComment tests that
exercise clients to validate getClientsSnapshotForState behavior: after calling
publishComment, read accountsStore.getState().accountsComments and locate the
stored comment for the publish session index (use
getPublishSession(publishSessionId).currentIndex or the same index used in the
test) and assert (1) when publication.clients contains client objects with
state/on, the accountsComments entry for that index contains a clients snapshot
equal to the expected shape produced by getClientsSnapshotForState; (2) when
publication.clients yields no snapshot (getClientsSnapshotForState returns
undefined), the stored comment has no clients key (clients was deleted by
syncCommentClientsSnapshot); and (3) for nested client structures, assert the
nested keys map to snapshots (state objects) matching the transformation.
Reference getClientsSnapshotForState, syncCommentClientsSnapshot and
maybeUpdateAccountComment to locate where to assert stored results in
accountsStore.

---

Nitpick comments:
In `@src/stores/accounts/accounts-actions.ts`:
- Around line 62-78: Add a short JSDoc above the getClientsSnapshotForState
function that documents the expected shape of the clients input (a nested object
tree whose leaves are client objects containing a state property, e.g.,
clients.ipfsGateways["url"].state) and explain the termination heuristic (treat
any object with a "state" property or an event-emitter-like "on" method as a
leaf). This clarifies why the function checks typeof clients.on === "function"
|| "state" in clients and warns maintainers that adding a plain "state" property
to a non-leaf container will change behavior.
- Around line 1104-1127: Extract the repeated deletions into a small helper
(e.g., stripTransientCommentFields) and call it for both persistedCommentWithCid
and liveCommentWithCid instead of repeating delete lines; locate where
persistedCommentWithCid and liveCommentWithCid are created (after
addShortAddressesToAccountComment/sanitizeStoredAccountComment and
sanitizeAccountCommentForState) and replace the eight delete statements with two
calls to that helper, ensuring it removes clients, publishingState, error, and
errors before calling accountsDatabase.addAccountComment and before building
updatedAccountComment for accountsStore.setState.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9486f3e5-cb72-4a68-b40b-08879b1bd4e8

📥 Commits

Reviewing files that changed from the base of the PR and between d27c43e and 3cdb706.

📒 Files selected for processing (3)
  • src/stores/accounts/accounts-actions.ts
  • src/stores/accounts/accounts-database.test.ts
  • src/stores/accounts/accounts-database.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/stores/accounts/accounts-database.ts
  • src/stores/accounts/accounts-database.test.ts

Comment on lines +62 to +102
const getClientsSnapshotForState = (clients: any): any => {
if (!clients || typeof clients !== "object") {
return undefined;
}
if (typeof clients.on === "function" || "state" in clients) {
return { state: clients.state };
}

const snapshot: Record<string, any> = {};
for (const key in clients) {
const childSnapshot = getClientsSnapshotForState(clients[key]);
if (childSnapshot !== undefined) {
snapshot[key] = childSnapshot;
}
}
return Object.keys(snapshot).length > 0 ? snapshot : undefined;
};

const syncCommentClientsSnapshot = (
publishSessionId: string,
accountId: string,
publication: any,
) => {
const session = getPublishSession(publishSessionId);
if (session?.currentIndex === undefined) {
return;
}

const snapshot = getClientsSnapshotForState(publication?.clients);
accountsStore.setState(({ accountsComments }) =>
maybeUpdateAccountComment(accountsComments, accountId, session.currentIndex, (ac, acc) => {
const updatedAccountComment = { ...acc };
if (snapshot === undefined) {
delete updatedAccountComment.clients;
} else {
updatedAccountComment.clients = snapshot;
}
ac[session.currentIndex] = updatedAccountComment;
}),
);
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify test coverage for the new helper functions by checking if tests exercise the publishComment flow with clients state changes.

echo "=== Checking for tests that exercise publishComment with clients ==="
rg -n -C5 'publishComment|clients|statechange' --type=ts src/stores/accounts/accounts-actions.test.ts | head -100

echo ""
echo "=== Checking for direct tests of getClientsSnapshotForState (if exported elsewhere) ==="
rg -n 'getClientsSnapshotForState' --type=ts

echo ""
echo "=== Checking for syncCommentClientsSnapshot references in tests ==="
rg -n 'syncCommentClientsSnapshot' --type=ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 4548


🏁 Script executed:

# Get the publishComment tests and their assertions
sed -n '565,620p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 2030


🏁 Script executed:

# Also check around line 604 for the other publishComment test
sed -n '590,640p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1985


🏁 Script executed:

# Search for any test that specifically mentions or checks 'clients' in the test file
rg -n 'clients' src/stores/accounts/accounts-actions.test.ts -A3 -B3

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 2501


🏁 Script executed:

# Look at the assertions in the clients-related tests
sed -n '2021,2084p' src/stores/accounts/accounts-actions.test.ts | tail -60

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 2512


🏁 Script executed:

# Check the other clients tests assertions
sed -n '2086,2150p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 2823


🏁 Script executed:

# Check if there are any assertions about clients being present/absent in the stored comments
rg -n 'expect.*clients' src/stores/accounts/accounts-actions.test.ts -B5 -A2

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Look at the complete test for clients.ipfsGateways to see all assertions
sed -n '2121,2160p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1867


🏁 Script executed:

# Search for any assertion that checks whether clients are present or absent in stored comments
rg -n 'clients' src/stores/accounts/accounts-actions.test.ts | grep -i 'expect\|assert\|undefined\|delete'

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Check the full content of the test to see what it actually asserts about clients
sed -n '2121,2155p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1748


🏁 Script executed:

# Check if there's any verification of the comment structure stored in accountsComments
rg -n 'accountsComments' src/stores/accounts/accounts-actions.test.ts -A2 -B2 | head -80

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 3603


🏁 Script executed:

# Check what assertions exist in the clients edge case test (after the state clear/emit)
sed -n '2086,2125p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1833


🏁 Script executed:

# Also check the chainProviders test for assertions
sed -n '2021,2055p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1588


🏁 Script executed:

# Check if there are any tests that specifically verify clients is NOT in the stored comment
rg -n 'NOT.*clients|!.*clients|undefined.*clients|delete.*clients' src/stores/accounts/accounts-actions.test.ts -B3 -A3

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Check for any assertions after the setTimeout in the chainProviders test
sed -n '2021,2080p' src/stores/accounts/accounts-actions.test.ts | tail -40

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1851


🏁 Script executed:

# Search for tests that specifically check what's NOT in the stored comment (clients should be removed or transformed)
rg -n 'toEqual|toStrictEqual' src/stores/accounts/accounts-actions.test.ts | grep -i 'client\|comment' -B2 -A2

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Get the full test file size and look for all test names containing "client"
wc -l src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 127


🏁 Script executed:

# Find all test names related to clients
rg -n 'test\(' src/stores/accounts/accounts-actions.test.ts | grep -i 'client'

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 508


🏁 Script executed:

# Check what the storedComment structure looks like in tests - does it verify clients?
sed -n '1345,1365p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 975


🏁 Script executed:

# Look at the line where getClientsSnapshotForState is used at line 1202
sed -n '1195,1210p' src/stores/accounts/accounts-actions.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1062


🏁 Script executed:

# Check if any test verifies the clients property in stored comments
rg -n '\\.clients' src/stores/accounts/accounts-actions.test.ts -B2 -A2

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Check if there are any test assertions that validate the clients snapshot behavior
rg -n 'expect.*storedComment' src/stores/accounts/accounts-actions.test.ts | head -20

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 487


🏁 Script executed:

# Look for tests that specifically verify clients property in stored comment
rg -n 'storedComment.*clients|clients.*stored' src/stores/accounts/accounts-actions.test.ts -B3 -A3

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


🏁 Script executed:

# Check the full test around line 2121 to see all its assertions
sed -n '2121,2160p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1867


🏁 Script executed:

# Check if there are any assertions inside the client tests that we might have missed
sed -n '2021,2084p' src/stores/accounts/accounts-actions.test.ts | grep -n 'expect\|assert'

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 114


🏁 Script executed:

# Check the full chainProviders test to see if it has any assertions we missed
sed -n '2021,2055p' src/stores/accounts/accounts-actions.test.ts

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 1588


🏁 Script executed:

# Look for any test that validates the snapshot behavior or clients structure
rg -n 'getClientsSnapshot|snapshot' src/stores/accounts/accounts-actions.test.ts -B2 -A2

Repository: bitsocialnet/bitsocial-react-hooks

Length of output: 60


Add assertions to verify getClientsSnapshotForState snapshot behavior in tests.

The three publishComment tests that exercise clients (chainProviders, ipfsGateways, clientsOnStateChange) have no assertions verifying the snapshot transformation. Tests at lines 2021, 2086, and 2121 run publishComment with clients but don't assert on the resulting stored client snapshot. Add assertions to verify that:

  • Clients are properly snapshotted and stored in accountsComments
  • Undefined clients are handled correctly (deleted from stored comment)
  • The snapshot transformation works for nested clients structures

This is required per coding guidelines: mandatory 100% test coverage for stores must include verification of function behavior, not just execution of code paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stores/accounts/accounts-actions.ts` around lines 62 - 102, Add
assertions in the three publishComment tests that exercise clients to validate
getClientsSnapshotForState behavior: after calling publishComment, read
accountsStore.getState().accountsComments and locate the stored comment for the
publish session index (use getPublishSession(publishSessionId).currentIndex or
the same index used in the test) and assert (1) when publication.clients
contains client objects with state/on, the accountsComments entry for that index
contains a clients snapshot equal to the expected shape produced by
getClientsSnapshotForState; (2) when publication.clients yields no snapshot
(getClientsSnapshotForState returns undefined), the stored comment has no
clients key (clients was deleted by syncCommentClientsSnapshot); and (3) for
nested client structures, assert the nested keys map to snapshots (state
objects) matching the transformation. Reference getClientsSnapshotForState,
syncCommentClientsSnapshot and maybeUpdateAccountComment to locate where to
assert stored results in accountsStore.

@tomcasaburi tomcasaburi merged commit f2f8b4c into master Mar 20, 2026
8 checks passed
@tomcasaburi tomcasaburi deleted the fix/account-history-deep-compaction branch March 20, 2026 12:26
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.

Existing accountComments exports remain bloated with runtime payloads

1 participant