Skip to content

feat(instantsearch): add connectFeeds connector for multifeed compositions#6964

Open
e-krebs wants to merge 7 commits intofeat/composition-multifeed-layer1-helperfrom
feat/composition-multifeed-layer2-connector
Open

feat(instantsearch): add connectFeeds connector for multifeed compositions#6964
e-krebs wants to merge 7 commits intofeat/composition-multifeed-layer1-helperfrom
feat/composition-multifeed-layer2-connector

Conversation

@e-krebs
Copy link
Copy Markdown
Contributor

@e-krebs e-krebs commented Apr 10, 2026

Summary

Layer 2 of the Multifeed Composition Support (RFC). Stacked on feat/composition-multifeed-layer1-helper (PR #6954).

  • connectFeeds connector: follows connectDynamicWidgets pattern — validates compositionID, creates/reuses/removes FeedContainer widgets per feed, supports transformFeeds for reordering/filtering, single-feed backward compat
  • FeedContainer: implements IndexWidget with $$type: 'ais.feedContainer', _isolated: true. Reads per-feed results from parentIndex.getResults().feeds by feedID. Shares parent helper, delegates URL/search to parent, propagates child widget lifecycle
  • Centralized indexWidgetTypes: single source of truth (const + type) for index-like widget types, used by isIndexWidget, IndexWidgetDescription, BuiltinTypes, BuiltinWidgetTypes
  • storeRenderState extraction: moved from module-private in index.ts to shared util in render-args.ts
  • Metadata middleware fix: uses isIndexWidget() instead of hardcoded 'ais.index' check — crawler now sees widgets inside feed containers (separate commit for cherry-pick)

Key design decisions

  • searchScope: 'global' required — future-proofing for per-feed search parameters (see RFC)
  • FeedContainer in parent widget treewalkIndex finds them (needed for SSR), addWidgets triggers scheduleSearch (includes facet declarations from child widgets)
  • Deferred container removalsetTimeout(() => parent.removeWidgets(...), 0), same as connectDynamicWidgets

Test plan

  • 41 unit tests for FeedContainer and connectFeeds (identity, lifecycle, delegation, results lookup, container management, transformFeeds, backward compat, dispose)
  • TypeScript: yarn workspace instantsearch.js tsc --noEmit — no new errors
  • Helper tests: yarn workspace algoliasearch-helper test — 456 pass
  • CI green

🤖 Generated with Claude Code

@codacy-production
Copy link
Copy Markdown

codacy-production bot commented Apr 10, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 186 complexity · 0 duplication

Metric Results
Complexity 186
Duplication 0

View in Codacy

TIP This summary will be updated as you push new changes. Give us feedback

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 10, 2026

More templates

algoliasearch-helper

npm i https://pkg.pr.new/algolia/instantsearch/algoliasearch-helper@6964

instantsearch-ui-components

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch-ui-components@6964

instantsearch.css

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch.css@6964

instantsearch.js

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch.js@6964

react-instantsearch

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch@6964

react-instantsearch-core

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-core@6964

react-instantsearch-nextjs

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-nextjs@6964

react-instantsearch-router-nextjs

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-router-nextjs@6964

vue-instantsearch

npm i https://pkg.pr.new/algolia/instantsearch/vue-instantsearch@6964

commit: 89f8509

@e-krebs e-krebs force-pushed the feat/composition-multifeed-layer2-connector branch from d420bf0 to 61738c6 Compare April 10, 2026 09:33
@e-krebs e-krebs marked this pull request as ready for review April 10, 2026 09:42
@e-krebs e-krebs requested review from a team, FabienMotte and aymeric-giraudet and removed request for a team April 10, 2026 09:42
});
if (containersToRemove.length > 0) {
// Deferred removal — same pattern as connectDynamicWidgets
setTimeout(() => parent.removeWidgets(containersToRemove), 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in dynamic widgets we have the connector being responsible for adding/removing the widgets, but in the end in react and vue we're not really using it and the logic is in the widget instead of the connector. Is that similar here, do you see a better approach?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure yet to be honest, I can keep that in mind once working on the react & vue widgets in the next PR.
but even if we end up with a similar approach (where in react and vue the logic is in the widget), this connector logic is still useful for the vanilla.js version, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be useful, but in retrospect I think I would have preferred the logic for the js widget to be all in the widget too. Depends what it looks like, the logic still may be easy to move.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, the js widget is next step so I'll see if that approach works 🙂

e-krebs and others added 7 commits April 10, 2026 14:27
Move storeRenderState from module-private in index.ts to render-args.ts
so FeedContainer can reuse it in the feeds connector (Layer 2).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dContainer

Introduce indexWidgetTypes const and IndexWidgetType as single source of
truth for index-like widget types. Update isIndexWidget, IndexWidgetDescription,
BuiltinTypes, and BuiltinWidgetTypes to use them. Add 'ais.feeds' and
'ais.feedContainer' to builtin type unions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The metadata middleware hardcoded 'ais.index' instead of using
isIndexWidget, so widgets inside feed containers were invisible
to the Algolia Crawler metadata.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@e-krebs e-krebs force-pushed the feat/composition-multifeed-layer2-connector branch from 61738c6 to 89f8509 Compare April 10, 2026 12:27
@e-krebs e-krebs requested a review from Haroenv April 10, 2026 12:36
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.

2 participants