import {useWorker} from '@sanity/sdk-react/dashboard'
import {useMemo} from 'react'
import {useObservable} from 'react-rx'
import {filter, Observable, scan, share, startWith, switchMap} from 'rxjs'
type Feed = {payload: {feed: 'inbox'}; reply: Snapshot; message: FeedMessage}
function Inbox() {
const feed = useWorker<Feed>('feed')
const inbox$ = useMemo(() => {
const messages$ = new Observable<FeedMessage>((subscriber) =>
feed.subscribe((message) => subscriber.next(message)),
).pipe(share())
return messages$.pipe(
filter((message) => message.type === 'welcome'),
startWith(null),
switchMap(() => feed.post({feed: 'inbox'})),
switchMap((snapshot) => messages$.pipe(scan(apply, snapshot), startWith(snapshot))),
)
}, [feed])
const inbox = useObservable(inbox$)
return <List items={inbox?.items ?? []} />
}
Returns a client for one of the application's own workers, named by service. The client is the same object for the same name, even across a render that suspended, so it can key caches.
A worker's messages aren't stored, so a view that starts listening later misses earlier ones. Listen first, then post for what you need. Have the worker send a message when it starts, such as
welcome, so views that are already listening post again.