MCPcopy Create free account
hub / github.com/TanStack/db / createFilteredCallback

Function createFilteredCallback

packages/db/src/collection/change-events.ts:250–308  ·  view source on GitHub ↗
(
  originalCallback: (changes: Array<ChangeMessage<T>>) => void,
  options: SubscribeChangesOptions<T, TKey>,
)

Source from the content-addressed store, hash-verified

248 * @returns A filtered callback function
249 */
250export function createFilteredCallback<
251 T extends object,
252 TKey extends string | number = string | number,
253>(
254 originalCallback: (changes: Array<ChangeMessage<T>>) => void,
255 options: SubscribeChangesOptions<T, TKey>,
256): (changes: Array<ChangeMessage<T>>) => void {
257 const filterFn = createFilterFunctionFromExpression(options.whereExpression!)
258
259 return (changes: Array<ChangeMessage<T>>) => {
260 const filteredChanges: Array<ChangeMessage<T>> = []
261
262 for (const change of changes) {
263 if (change.type === `insert`) {
264 // For inserts, check if the new value matches the filter
265 if (filterFn(change.value)) {
266 filteredChanges.push(change)
267 }
268 } else if (change.type === `update`) {
269 // For updates, we need to check both old and new values
270 const newValueMatches = filterFn(change.value)
271 const oldValueMatches = change.previousValue
272 ? filterFn(change.previousValue)
273 : false
274
275 if (newValueMatches && oldValueMatches) {
276 // Both old and new match: emit update
277 filteredChanges.push(change)
278 } else if (newValueMatches && !oldValueMatches) {
279 // New matches but old didn't: emit insert
280 filteredChanges.push({
281 ...change,
282 type: `insert`,
283 })
284 } else if (!newValueMatches && oldValueMatches) {
285 // Old matched but new doesn't: emit delete
286 filteredChanges.push({
287 ...change,
288 type: `delete`,
289 value: change.previousValue!, // Use the previous value for the delete
290 })
291 }
292 // If neither matches, don't emit anything
293 } else {
294 // For deletes, include if the previous value would have matched
295 // (so subscribers know something they were tracking was deleted)
296 if (filterFn(change.value)) {
297 filteredChanges.push(change)
298 }
299 }
300 }
301
302 // Always call the original callback if we have filtered changes OR
303 // if the original changes array was empty (which indicates a ready signal)
304 if (filteredChanges.length > 0 || changes.length === 0) {
305 originalCallback(filteredChanges)
306 }
307 }

Callers 1

constructorMethod · 0.85

Calls 2

filterFnFunction · 0.85

Tested by

no test coverage detected