Skip to content

Commit 13dd85d

Browse files
committed
Allow reuse position
1 parent 3ff6f3b commit 13dd85d

1 file changed

Lines changed: 26 additions & 10 deletions

File tree

  • packages/core/src/reducers/activities/sort

packages/core/src/reducers/activities/sort/upsert.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ const INITIAL_STATE = Object.freeze({
2525
sortedChatHistoryList: Object.freeze([])
2626
} satisfies State);
2727

28+
// Question: Why insertion sort works but not quick sort?
29+
// Short answer: Arrival order matters.
30+
// Long answer:
31+
// - Update activity: when replacing an activity, and data from their previous revision still matters
32+
// - Duplicate timestamps: activities without timestamp is consider duplicate value and can't be sort deterministically
33+
2834
function upsert(ponyfill: Pick<GlobalScopePonyfill, 'Date'>, state: State, activity: Activity): State {
2935
const nextActivityMap = new Map(state.activityMap);
3036
const nextLivestreamSessionMap = new Map(state.livestreamingSessionMap);
@@ -33,6 +39,7 @@ function upsert(ponyfill: Pick<GlobalScopePonyfill, 'Date'>, state: State, activ
3339

3440
const activityInternalId = getActivityInternalId(activity);
3541
const logicalTimestamp = getLogicalTimestamp(activity, ponyfill);
42+
let shouldReusePosition = true;
3643

3744
nextActivityMap.set(
3845
activityInternalId,
@@ -63,6 +70,11 @@ function upsert(ponyfill: Pick<GlobalScopePonyfill, 'Date'>, state: State, activ
6370
(nextLivestreamingSession ? nextLivestreamingSession.finalized : false) ||
6471
activityLivestreamingMetadata.type === 'final activity';
6572

73+
// If livestream become finalized in this round, update the position once.
74+
if (finalized && !nextLivestreamingSession?.finalized) {
75+
shouldReusePosition = false;
76+
}
77+
6678
const nextLivestreamingSessionMapEntry = {
6779
activities: Object.freeze(
6880
insertSorted<LivestreamSessionMapEntryActivityEntry>(
@@ -167,16 +179,20 @@ function upsert(ponyfill: Pick<GlobalScopePonyfill, 'Date'>, state: State, activ
167179
: // eslint-disable-next-line no-magic-numbers
168180
-1;
169181

170-
~existingSortedChatHistoryListEntryIndex &&
171-
nextSortedChatHistoryList.splice(existingSortedChatHistoryListEntryIndex, 1);
172-
173-
nextSortedChatHistoryList = insertSorted(
174-
nextSortedChatHistoryList,
175-
Object.freeze(sortedChatHistoryListEntry),
176-
({ logicalTimestamp: x }, { logicalTimestamp: y }) =>
177-
// eslint-disable-next-line no-magic-numbers
178-
typeof x === 'undefined' || typeof y === 'undefined' ? -1 : x - y
179-
);
182+
if (shouldReusePosition && ~existingSortedChatHistoryListEntryIndex) {
183+
nextSortedChatHistoryList[+existingSortedChatHistoryListEntryIndex] = Object.freeze(sortedChatHistoryListEntry);
184+
} else {
185+
~existingSortedChatHistoryListEntryIndex &&
186+
nextSortedChatHistoryList.splice(existingSortedChatHistoryListEntryIndex, 1);
187+
188+
nextSortedChatHistoryList = insertSorted(
189+
nextSortedChatHistoryList,
190+
Object.freeze(sortedChatHistoryListEntry),
191+
({ logicalTimestamp: x }, { logicalTimestamp: y }) =>
192+
// eslint-disable-next-line no-magic-numbers
193+
typeof x === 'undefined' || typeof y === 'undefined' ? -1 : x - y
194+
);
195+
}
180196

181197
// #endregion
182198

0 commit comments

Comments
 (0)