useQuery accepts throttleMs in its options type but never passes it down, so you always get the 30ms default. Nothing warns.
The options object it builds for useWatchedQuery is just:
{
reportFetching: options.reportFetching,
rowComparator: options.rowComparator
}
useWatchedQuery does read hookOptions.throttleMs (in differentialWatch, watch, and updateSettings), so it's only that literal that's missing it.
// types fine, still throttles at 30ms
const { data } = useQuery('SELECT * FROM lists', [], { throttleMs: 200 });
Hit this on @powersync/react@2.0.0, and packages/react/src/hooks/watched/useQuery.ts on main looks the same today. Also reproduced on 1.10.0, so it isn't new.
While I was in there I noticed the hook's options type comes from the callback API rather than the watched-query one:
HookWatchOptions extends Omit<SQLOnChangeOptions, 'signal'>
so tables and triggerImmediate type-check too, and are also dropped. Those two have no equivalent in WatchedQueryOptions so they could never have applied. triggerOnTables — the one that would actually limit trigger tables — isn't on the hook type at all. throttleMs seems to be the only one of the four that's both advertised and implementable. The type lineage might be worth a separate look, though changing it would break anyone passing the dead keys.
Two small things I ran into:
Passing throttleMs isn't entirely inert. checkQueryChanged does JSON.stringify(options) on the raw user options, so changing it between renders flips queryChanged and fires an updateSettings({ throttleMs: undefined }).
useSuspenseQuery is unaffected — QueryStore.getQuery forwards throttleMs properly.
The fix looks like one line:
options: {
reportFetching: options.reportFetching,
+ throttleMs: options.throttleMs,
rowComparator: options.rowComparator
},
Workaround for anyone who finds this first, since both exports are public:
const lists = db.query({ sql, parameters }).differentialWatch({ rowComparator, throttleMs: 200 });
const { data } = useWatchedQuerySubscription(lists);
useQueryacceptsthrottleMsin its options type but never passes it down, so you always get the 30ms default. Nothing warns.The options object it builds for
useWatchedQueryis just:useWatchedQuerydoes readhookOptions.throttleMs(indifferentialWatch,watch, andupdateSettings), so it's only that literal that's missing it.Hit this on
@powersync/react@2.0.0, andpackages/react/src/hooks/watched/useQuery.tson main looks the same today. Also reproduced on 1.10.0, so it isn't new.While I was in there I noticed the hook's options type comes from the callback API rather than the watched-query one:
so
tablesandtriggerImmediatetype-check too, and are also dropped. Those two have no equivalent inWatchedQueryOptionsso they could never have applied.triggerOnTables— the one that would actually limit trigger tables — isn't on the hook type at all.throttleMsseems to be the only one of the four that's both advertised and implementable. The type lineage might be worth a separate look, though changing it would break anyone passing the dead keys.Two small things I ran into:
Passing
throttleMsisn't entirely inert.checkQueryChangeddoesJSON.stringify(options)on the raw user options, so changing it between renders flipsqueryChangedand fires anupdateSettings({ throttleMs: undefined }).useSuspenseQueryis unaffected —QueryStore.getQueryforwardsthrottleMsproperly.The fix looks like one line:
options: { reportFetching: options.reportFetching, + throttleMs: options.throttleMs, rowComparator: options.rowComparator },Workaround for anyone who finds this first, since both exports are public: