diff --git a/docs/api/utils/combineKeys.md b/docs/api/utils/combineKeys.md index 7b9f49e..0fb32b0 100644 --- a/docs/api/utils/combineKeys.md +++ b/docs/api/utils/combineKeys.md @@ -8,7 +8,7 @@ of each key. ```ts export const combineKeys = ( - keys$: Observable | Set>, + keys$: Observable | KeyChanges>, getInner$: (key: K) => Observable, ): Observable> ``` @@ -53,8 +53,8 @@ const petRace$ = petUpdate$.pipe(startWith( ...petNames.map((pet, id): Pet => ({pet, id, pos: 1})), )); -const [petByID, petIds$] = partitionByKey(petRace$, x => x.id) -const keyMap$ = combineKeys(petIds$, petByID); +const [petByID, petIdChange$] = partitionByKey(petRace$, x => x.id) +const keyMap$ = combineKeys(petIdChange$, petByID); const leadingPet$ = keyMap$.pipe(map(x => // map to pet with highest pos Array.from(x.entries()) @@ -76,7 +76,6 @@ const advancingPet$: Observable = interval(1000).pipe( tap(updatePet), ); -const [usePetIDs] = bind(petIds$); const [usePetByID] = bind((petId:number) => petByID(petId)); const [useLeader] = bind(leadingPet$, null); const [useAdvancingPet] = bind(advancingPet$, null); diff --git a/docs/api/utils/partitionByKey.md b/docs/api/utils/partitionByKey.md index 894245c..9952b57 100644 --- a/docs/api/utils/partitionByKey.md +++ b/docs/api/utils/partitionByKey.md @@ -11,7 +11,12 @@ export function partitionByKey( stream: Observable, keySelector: (value: T) => K, streamSelector: (grouped: Observable, key: K) => Observable, -): [(key: K) => GroupedObservable, Observable] +): [(key: K) => GroupedObservable, Observable>] + +interface KeyChanges { + type: "add" | "remove" + keys: Iterable +} ``` #### Arguments @@ -26,13 +31,13 @@ export function partitionByKey( 1. A function that accepts a key and returns a stream for the group of that key. -2. A stream with the list of active keys +2. A stream of KeyChanges, an object the describes what keys have been added or deleted. ### Examples ```ts const source = interval(1000); -const [getGroupByKey, keys$] = partitionByKey( +const [getGroupByKey, keyChanges$] = partitionByKey( source, x => x % 2 == 0 ? "even" : "odd", (groupedObservable$, key) => groupedObservable$.pipe(map(x => `${x} is ${key}`)) @@ -40,7 +45,12 @@ const [getGroupByKey, keys$] = partitionByKey( const [useEven, even$] = bind(getGroupByKey("even")); const [useOdd, odd$] = bind(getGroupByKey("odd")); -const [useKeys] = bind(keys$); +const [useKeys] = bind( + keys$.pipe( + toKeySet(), + map(keySet => Array.from(keySet)) + ) +); function MyComponent() { const odd = useOdd(); @@ -76,13 +86,16 @@ const [petUpdate$, updatePet] = createSignal(); // Let's line up our pets const petRace$ = merge(of(...petNames), petUpdate$); -const [petByID, petIds$] = partitionByKey( +const [petByID, petIdChange$] = partitionByKey( petRace$, x => x.id, ) const [usePetByID] = bind((id: number) => petByID(id)); -const [usePetIDs] = bind(petIds$); +const [usePetIDs] = bind(petIdChange$.pipe( + toKeySet(), + map(keySet => Array.from(keySet)) +)); const PetItem = ({petID}: {petID: number}) => { const pet = usePetByID(petID); @@ -111,3 +124,4 @@ const PetList = () => { ## See also - [`combineKeys()`](combineKeys) +- [`toKeySet()`](toKeySet) diff --git a/docs/api/utils/toKeySet.md b/docs/api/utils/toKeySet.md new file mode 100644 index 0000000..bcbcc1d --- /dev/null +++ b/docs/api/utils/toKeySet.md @@ -0,0 +1,64 @@ +--- +title: toKeySet() +sidebar_label: toKeySet() +--- + +Operator function that maps a stream of KeyChanges into a Set that contains the +active keys. + +```ts +function toKeySet(): OperatorFunction, Set> +``` + +#### Returns + +An [OperatorFunction] that will aggregate the key changes from the stream into +a Set with those keys. + +### Example + +```ts +// Call to service mocked for the example +const priceStream$ = from([ + { + symbol: "AUDCHF", + price: 1.32, + }, + { + symbol: "GOLD", + price: 1.213, + }, + { + symbol: "CRYPTO", + price: 2.45, + }, + { + symbol: "GOLD", + price: 1.27, + }, +]).pipe( + // Add delay to every new price. + concatMap((value) => of(value).pipe(delay(100))), +) + +const [lastPriceOfSymbol, symbolChange$] = partitionByKey( + priceStream$, + (x) => x.symbol, +) + +const activeSymbols$ = toKeySet(symbolChange$).pipe( + map((keySet) => Array.from(keySet)), +) + +activeSymbols$.subscribe((keys) => console.log(keys)) +// Will log: +// ['AUDCHF'] +// ['AUDCHF', 'GOLD'] +// ['AUDCHF', 'GOLD', 'CRYPTO'] +``` + +## See also + +- [`partitionByKey()`](partitionByKey) + +[operatorfunction]: https://rxjs.dev/api/index/interface/OperatorFunction diff --git a/sidebars.js b/sidebars.js index 83fcd52..c45a91e 100644 --- a/sidebars.js +++ b/sidebars.js @@ -31,6 +31,7 @@ module.exports = { "api/utils/suspend", "api/utils/suspended", "api/utils/switchMapSuspended", + "api/utils/toKeySet", { type: "category", label: "Deprecated",