Skip to content

SourceSyncResult

The result of a source sync: the documents fetched this run and, optionally, the cursor the feed should advance to. A source may also return a bare Document[] for convenience — runSource normalizes that to { documents } with no cursor change.

PropertyTypeDescription
cursor?CursorThe cursor to advance the feed’s cursor to. Omit (or return { type: 'none' }) to leave the cursor unchanged — the two are synonyms, and the platform now genuinely treats them as such. The old wording here claimed “the cloud only advances if the new value is monotonically ahead (compare-and-swap)”. Half of that was wrong and worth correcting rather than deleting: there IS a compare-and-swap, but it is against the cursor the round STARTED from — it stops two concurrent syncs clobbering each other. Nothing compares cursor values for ordering. Returning an older date than the stored one moves the feed backwards, and this is the layer that decides what to return.
documentsDocument[]The documents fetched this run, mapping 1:1 onto IngestDocumentInput.
feedName?stringWhat the feed calls itself, when the source learned it this run. Trove adopts it, so a feed shows a name rather than the URL somebody pasted. Absent for a source that has nothing better to offer than what the user typed — never a guess.
feedUrl?stringWhere the feed now lives, when it has permanently moved. A feed that 301s to a new address can say so once, instead of every future run paying for the redirect — and a feed that moves without saying so eventually stops resolving at all.
stats?{ [counter: string]: number | undefined; fetched?: number; remaining?: number; skipped?: number; undated?: number; }What this run did, as counters. remaining is the only key anything reads — the runner drains on it. The rest are a source’s own bookkeeping, useful when a run is being debugged and inert otherwise; blocked, waiting, unparseable, saved and duration_ms are all in use. The named fields below are the ones enough sources share to be worth documenting, not a closed set — which is why the index signature is here rather than a fifth, sixth and seventh field being added one failing typecheck at a time. Counters, though: prose belongs in ctx.log, which is persisted as the run transcript and shown to the user. A source that put a string[] of warnings here was duplicating lines it had already logged, into a field nothing reads.
stats.fetched?numberHow many documents this run produced.
stats.remaining?numberHow many the source knows are still waiting, when it can tell. The number the runner drains on: > 0 means go again now rather than wait for the next scheduled tick, so a backfill finishes in one sitting. This is the ONE key with behaviour attached — spell it right.
stats.skipped?numberHow many candidates this run passed over — already seen, out of window, or filtered out by config. Reported so a run that returns nothing can be told apart from a run that found nothing.
stats.undated?numberHow many of the returned documents carry no usable date. A date-cursor source cannot resume past an undated document, so a feed quietly producing them is a feed that will re-read the same window forever.