@recursiv/sdk 0.7.40 → 0.7.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -124,20 +124,28 @@ export class DiscoveryFeedSession {
124
124
  this.seen.delete(this.seen.values().next().value);
125
125
  const modules = [];
126
126
  const page = this.page++;
127
- for (let index = 0; index < mixed.length;) {
128
- const first = mixed[index];
127
+ let remaining = mixed;
128
+ while (remaining.length) {
129
+ const index = modules.length;
130
+ const first = remaining[0];
129
131
  const proposal = first.layout.source === 'jev' ? first.layout.presentation : 'posts';
130
132
  const preferred = this.learning?.choose(proposal, page) ?? proposal;
131
- const group = mixed.slice(index, index + 4);
133
+ // Feature eligible posts within a small window, retaining the other posts
134
+ // in their original order. A gallery must not begin with a text-only card
135
+ // merely because nearby posts provided enough images for the layout.
136
+ const group = remaining.slice(0, 8);
137
+ const images = group.filter(row => row.item.post.media?.some(media => media.type === 'image')).slice(0, 4);
138
+ const conversations = group.filter(row => row.item.kind === 'social' ? (row.item.post.replyCount ?? 0) > 0 : (row.item.post.reply_count ?? 0) > 0).slice(0, 4);
132
139
  const video = preferred === 'video' && first.item.post.media?.some(media => media.type === 'video');
133
- const visual = preferred === 'visual' && group.filter(row => row.item.post.media?.some(media => media.type === 'image')).length >= 2;
134
- const discussion = preferred === 'conversation' && group.filter(row => row.item.kind === 'social' ? (row.item.post.replyCount ?? 0) > 0 : (row.item.post.reply_count ?? 0) > 0).length >= 2;
140
+ const visual = preferred === 'visual' && images.length >= 2;
141
+ const discussion = preferred === 'conversation' && conversations.length >= 2;
135
142
  const presentation = video ? 'video' : visual ? 'visual' : discussion ? 'conversation' : 'posts';
136
- const selected = presentation === 'posts' || video ? [first] : group;
143
+ const selected = visual ? images : discussion ? conversations : [first];
137
144
  const items = selected.map(row => row.item);
138
145
  modules.push({ id: `discovery-${page}-${index}-${items[0].key}`, presentation, source: presentation === 'posts' ? 'fallback' : 'jev', items,
139
146
  spec: { root: 'module', elements: { module: { type: video ? 'DiscoveryVideo' : visual ? 'DiscoveryGallery' : discussion ? 'DiscoveryConversation' : 'DiscoveryPosts', props: { itemKeys: items.map(item => item.key) }, children: [] } } } });
140
- index += selected.length;
147
+ const selectedKeys = new Set(items.map(item => item.key));
148
+ remaining = remaining.filter(row => !selectedKeys.has(row.item.key));
141
149
  }
142
150
  return { modules, hasMore: this.streams.some(stream => !stream.done && !stream.failed),
143
151
  failedSources: this.streams.filter(stream => stream.failed).map(stream => stream.protocol), partialCategories: reads.some(read => read.partial) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@recursiv/sdk",
3
- "version": "0.7.40",
3
+ "version": "0.7.41",
4
4
  "description": "TypeScript SDK for the Recursiv API",
5
5
  "license": "FSL-1.1-ALv2",
6
6
  "type": "module",