From 6ebfea0f30a1d8ea24947380382969db616319cc Mon Sep 17 00:00:00 2001 From: Max Nowack Date: Mon, 11 Nov 2024 10:14:06 +0100 Subject: [PATCH] feat: allow specifying custom items merger for AutoFetchCollection --- docs/replication/index.md | 4 ++++ packages/signaldb/src/AutoFetchCollection.ts | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/replication/index.md b/docs/replication/index.md index 43ebbf1d..96f71b53 100644 --- a/docs/replication/index.md +++ b/docs/replication/index.md @@ -110,6 +110,10 @@ const Todos = new AutoFetchCollection({ // If a persistence adapter is used, the data is loaded first and will be updated after the server data is fetched // If the data will be updated, the data will be saved to the persistence adapter and pushed to the server simultaneously persistence: createLocalStorageAdapter('todos'), + + // Optionally you can also specify a mergeItems function to merge items + // if they're returned by multiple fetchQueryItems calls. + mergeItems: (itemA, itemB) => ({ ...itemA, ...itemB }), }) // You can also observe the loading state of the collection. diff --git a/packages/signaldb/src/AutoFetchCollection.ts b/packages/signaldb/src/AutoFetchCollection.ts index 23083862..8cf43368 100644 --- a/packages/signaldb/src/AutoFetchCollection.ts +++ b/packages/signaldb/src/AutoFetchCollection.ts @@ -10,6 +10,7 @@ interface AutoFetchOptions, I> { fetchQueryItems: (selector: Selector) => ReturnType['pull']>, purgeDelay?: number, registerRemoteChange?: (onChange: () => Promise) => Promise, + mergeItems?: (itemA: T, itemB: T) => T, } export type AutoFetchCollectionOptions< T extends BaseItem, @@ -35,6 +36,7 @@ export default class AutoFetchCollection< private reactivityAdapter: ReactivityAdapter | null = null private loadingSignals = new Map>() private isFetchingSignal: Signal + private mergeItems: (itemA: T, itemB: T) => T /** * @param options {Object} - Options for the collection. @@ -54,7 +56,7 @@ export default class AutoFetchCollection< newItems.push(item) return } - newItems[index] = { ...newItems[index], ...item } + newItems[index] = this.mergeItems(newItems[index], item) }) return newItems }, []), @@ -64,6 +66,7 @@ export default class AutoFetchCollection< return Promise.resolve() }, }) + this.mergeItems = options.mergeItems ?? ((itemA, itemB) => ({ ...itemA, ...itemB })) this.purgeDelay = options.purgeDelay ?? 10000 // 10 seconds this.isFetchingSignal = createSignal(options.reactivity?.create(), false) if (!triggerRemoteChange) throw new Error('No triggerRemoteChange method found. Looks like your persistence adapter was not registered')