Pagination and iteration
Traverse authorized account pages with query-bound cursors, lazy iteration, cancellation, and explicit page and item limits.
social.accounts.list returns one Page<AccountRecord>. A page contains items and may contain nextCursor. Pass that cursor unchanged with the same backend, tenant authorization, and page size to read the next page.
The client wraps provider cursors with their query scope. Switching the backend, tenant, or limit while reusing a cursor fails locally before the adapter runs. A cursor carries navigation state, not an authorization grant. The application still authorizes the accounts on every returned page. Avoid logging cursor contents because an upstream cursor may contain provider query details.
Iterate authorized accounts
social.accounts.iterate is lazy. Constructing its iterator does not fetch anything; requests begin when iteration starts. It uses the same account authorization policy as list.
import { createSocial } from "@opencoredev/social-sdk";
import { mockBackend } from "@opencoredev/social-sdk/testing";
const social = createSocial({ backend: mockBackend() });
const controller = new AbortController();
for await (const account of social.accounts.iterate({
backend: "default",
limit: 25,
maxPages: 10,
maxItems: 100,
signal: controller.signal,
})) {
console.log(account.displayName);
}
This complete mock example prints Mock Creator and Mock Studio without network calls. For a real multi-user client, pass the authenticated session in the iterator’s authorization option and configure the client’s authorization policy. Keep provider credentials on the server. See the mock quickstart for publication setup.
The default limits are 100 pages and 10,000 items. Reaching either limit ends iteration even if the backend has more results. Use explicit list calls when you need to retain a continuation cursor. Breaking out of the loop stops additional page requests. Aborting the signal interrupts traversal and passes cancellation to the active adapter request. Repeated or empty upstream cursors fail rather than creating an infinite loop.
Other page sources
The exported iterateItems helper accepts a callback that reads one page from a cursor. It supplies the same lazy traversal, repeat detection, and bounds. Pass the signal to both the helper and your underlying read operation. This helper does not add pagination to an adapter operation that only reads its first page.
Account pagination and iteration have deterministic tests under Node and Bun. Provider list endpoints may still have upstream history limits or changing results between requests. A completed traversal is a view of those responses, not a transactionally consistent snapshot.
Feeds, search, comments, and conversations
posts.list(account, options), social.search.posts(account, options), comments.list(post, options), messages.listConversations(account, options), messages.listMessages(conversation, options), notifications.list(account, options), and graph.listRelationships(account, options) accept cursor and limit. Their cursors bind the backend, tenant, account, resource, query where applicable, relationship kind, and page size. Pass the returned value unchanged. An adapter with no upstream continuation rejects a supplied cursor instead of returning page one again.
Use posts.iterate, search.iteratePosts, comments.iterate, messages.iterateConversations, messages.iterateMessages, or notifications.iterate for lazy bounded traversal. graph.listRelationships is page-based. Each iterator accepts the same maxPages, maxItems, and cancellation controls as account iteration. The capability manifest identifies which adapters implement each list operation.
Search cursors are provider cursors, not durable checkpoints. A provider may add, remove, or reorder matches while a query is being traversed. Persist a cursor only with the exact query and request scope that produced it, and stop when the provider omits nextCursor.