Skip to content

Filtering Feeds

When streaming data from views, you can control what the server sends to reduce bandwidth and improve performance.


All Hyperstack SDKs support these parameters when subscribing to feeds:

ParameterTypeDescription
takenumberMaximum number of entities to return
skipnumberNumber of entities to skip (for pagination)
keystringEntity key for state view subscriptions

Use take and skip to paginate through large datasets:

import { useHyperStack } from "hyperstack-react";
import { TOKEN_STACK } from "hyperstack-stacks/token";
function TokenList() {
const hs = useHyperStack(TOKEN_STACK);
const [page, setPage] = useState(1);
const pageSize = 10;
// Paginated subscription
const { data: tokens } = hs.views.Token.list.use({
take: pageSize,
skip: (page - 1) * pageSize,
});
return (
<div>
{tokens?.map(t => <TokenRow key={t.id.mint} token={t} />)}
<button onClick={() => setPage(p => p + 1)}>Next Page</button>
</div>
);
}

For state views, pass the entity key to subscribe to a specific entity:

const { data: token } = hs.views.Token.state.use(tokenAddress);

Beyond the default state and list views, stacks can define custom views with sorting and limits applied at the server level.

  • Reduced bandwidth - Server applies sorting/limits before transmitting
  • Consistent ordering - Sort order is defined once in your stack
  • Pre-configured limits - Useful for “top N” or “latest N” views

Custom views are defined using the #[view] attribute on your entity struct:

use hyperstack::prelude::*;
#[hyperstack(idl = "idl/ore.json")]
pub mod ore_stream {
#[entity(name = "OreRound")]
#[view(name = "latest", sort_by = "id.round_id", order = "desc")]
pub struct OreRound {
pub id: RoundId,
pub state: RoundState,
// ... other fields
}
}
ParameterTypeDescription
namestringView name (e.g., "latest")
sort_bystringField path to sort by (e.g., "id.round_id")
order"asc" | "desc"Sort order (default: "desc")
takenumberOptional limit on results

Custom views appear alongside the default views in your SDK:

import { useHyperStack } from "hyperstack-react";
import { ORE_STREAM_STACK } from "hyperstack-stacks/ore";
function LatestRounds() {
const hs = useHyperStack(ORE_STREAM_STACK);
// Default views
const { data: allRounds } = hs.views.OreRound.list.use();
const { data: round } = hs.views.OreRound.state.use(roundAddress);
// Custom view - sorted by round_id desc
const { data: latestRounds } = hs.views.OreRound.latest.use();
return <div>{latestRounds?.map(r => <Round key={r.id.round_id} round={r} />)}</div>;
}
#[entity(name = "Token")]
#[view(name = "topByVolume", sort_by = "metrics.total_volume", order = "desc", take = 10)]
pub struct Token {
pub id: TokenId,
pub metrics: TokenMetrics,
}
// Get top 10 tokens by volume
for await (const token of hs.views.Token.topByVolume.use()) {
console.log(token.id.mint, token.metrics.total_volume);
}

See Stack Definitions for complete documentation on defining entities and views.


If you need dynamic filtering that changes at runtime, apply filters client-side after receiving data:

The React SDK provides a where clause for declarative client-side filtering:

import { useHyperStack } from "hyperstack-react";
import { TOKEN_STACK } from "hyperstack-stacks/token";
function HighVolumeTokens() {
const hs = useHyperStack(TOKEN_STACK);
// Client-side filtering with where clause
const { data: tokens } = hs.views.Token.list.use({
where: {
volume: { gte: 10000 },
price: { lte: 100 }
},
limit: 20, // Client-side limit
});
return <TokenList tokens={tokens} />;
}

Supported where operators:

OperatorDescription
gteGreater than or equal
lteLess than or equal
gtGreater than
ltLess than
(value)Exact match