Skip to content

feat: generalize entity store in V10 - #1814

Open
isekovanic wants to merge 4 commits into
release-v10from
feat/generalize-entity-store
Open

feat: generalize entity store in V10#1814
isekovanic wants to merge 4 commits into
release-v10from
feat/generalize-entity-store

Conversation

@isekovanic

Copy link
Copy Markdown
Contributor

CLA

  • I have signed the Stream CLA (required).
  • Code changes are tested

Description of the changes, What, Why and How?

Generalizes the MessageStore into a reusable generic layer, makes the pinned message list reactive and collapses the ItemIndex abstraction to a single implementation.

What & Why

The reactive MessageStore and its MessageStoreBackedItemIndex were message specific, but nothing about them actually depends on message and the domain type is only used to pull an id. This PR lifts that into a generic, reusable core so any collection can share the same normalized/reactive machinery and removes redundant stuff.

1. MessageStore becomes generic EntityStore<T>

  • New EntityStore<T> holds the entire former store body; its constructor takes an options object { getId } (EntityStoreOptions<T>), matching the ItemIndex({ getId }) idiom
  • The MessageStore subclass is deleted since it existed only to bind getId. client.messageStore is now new EntityStore<LocalMessage>({ getId: (m) => m.id })
  • MessageStoreBackedItemIndex becomes a generic StoreBackedItemIndex<T>, with an optional store (falls back to a private EntityStore, so a detached index behaves like a plain per-instance one)

2. Pinned message list is now store backed

  • The store backed ItemIndex factory has been moved up to MessageIntervalPaginator (common ancestor of the main list, thread replies and pinned list), so PinnedMessagePaginator now shares the client global store instead of holding a private ItemIndex
  • I somehow forgot to do this in the previous reactive collections PR, even though this is exactly what prompted that architectural design in the first place 😅

3. Delete the standalone ItemIndex class

  • With the store now optional, a storeless StoreBackedItemIndex is behaviorally identical to the old ItemIndex. owner is now optional too and so the four remaining new ItemIndex(...) sites (Base default, Channel/Reminder/UserGroup paginators) route through StoreBackedItemIndex.
  • The ItemIndex class and ItemIndexOptions are removed; the ItemIndexApi interface (the contract BasePaginator depends on) is kept, now with a single implementation

Public API surface

Removed Added
MessageStore (class) EntityStore (class)
MessageStoreChangeBatch EntityStoreChangeBatch
MessageStoreSubscriber EntityStoreSubscriber
EntityStoreOptions

Testing

  • yarn types, yarn lint (0 warnings), yarn build all clean.
  • Full unit suite green. New coverage: pinned-message fan-out (reactions.optimistic.test.ts) and owner-less/store-less CRUD (StoreBackedItemIndex.test.ts). The ItemIndex.test.ts suite was folded into StoreBackedItemIndex.test.ts.
  • Consuming SDKs verified unaffected — the renamed symbols have no importers in stream-chat-react-native.

Changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant