Compare commits

..

1 Commits

Author SHA1 Message Date
Dean Wenstrand
8441bb12e9 Select stream.id in upload-status operations so the cache stays normalized
All checks were successful
Tests / Tests (pull_request) Successful in 11s
UploadStreamWithDetails and the editUploadStream response selected
stream fields without id. Apollo cannot normalize an object with no id
selected, so every upload-service poll rewrote VideoGQL.stream as an
anonymous inline object — clobbering the id that feed/detail queries
select. Their cache reads went partial and useQuery silently fell back
to the last network result, rendered as the home feed collapsing to
the first page (and bouncing the viewport) whenever an upload was
polling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 19:27:25 -07:00
4 changed files with 1599 additions and 1718 deletions

View File

@@ -2404,11 +2404,6 @@ export type Header = {
value: Scalars["String"]["output"];
};
export enum HomographyBackendGql {
Classic = "CLASSIC",
Tablenet = "TABLENET",
}
export type HomographyInfoGql = {
__typename?: "HomographyInfoGQL";
crop: BoundingBoxGql;
@@ -3195,28 +3190,14 @@ export type QueryGetLiveTableStateArgs = {
};
export type QueryGetLongestRunsLeaderboardArgs = {
excludeDrills?: Scalars["Boolean"]["input"];
gameType?: InputMaybe<Scalars["String"]["input"]>;
interval?: InputMaybe<TimeInterval>;
limit?: Scalars["Int"]["input"];
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
rankedOnly?: Scalars["Boolean"]["input"];
requiredTags?: InputMaybe<Array<Scalars["String"]["input"]>>;
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
};
export type QueryGetMakesLeaderboardArgs = {
excludeDrills?: Scalars["Boolean"]["input"];
gameType?: InputMaybe<Scalars["String"]["input"]>;
interval?: InputMaybe<TimeInterval>;
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
rankedOnly?: Scalars["Boolean"]["input"];
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
};
@@ -4297,7 +4278,6 @@ export type VideoMetadataInput = {
framesPerSecond?: InputMaybe<Scalars["Float"]["input"]>;
/** @deprecated `game_type` is deprecated. Use `tags` instead. */
gameType?: InputMaybe<Scalars["String"]["input"]>;
homographyBackend?: InputMaybe<HomographyBackendGql>;
lastIntendedSegmentBound?: InputMaybe<Scalars["Int"]["input"]>;
pocketSize?: InputMaybe<Scalars["Float"]["input"]>;
private?: InputMaybe<Scalars["Boolean"]["input"]>;
@@ -5236,11 +5216,6 @@ export type GetVideoFeedQuery = {
export type GetMakesLeaderboardQueryVariables = Exact<{
interval?: InputMaybe<TimeInterval>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
gameType?: InputMaybe<Scalars["String"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
}>;
export type GetMakesLeaderboardQuery = {
@@ -5265,11 +5240,6 @@ export type GetMakesLeaderboardQuery = {
export type GetRunsLeaderboardQueryVariables = Exact<{
interval?: InputMaybe<TimeInterval>;
when?: InputMaybe<Scalars["DateTime"]["input"]>;
gameType?: InputMaybe<Scalars["String"]["input"]>;
tableSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
tableSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMin?: InputMaybe<Scalars["Float"]["input"]>;
pocketSizeMax?: InputMaybe<Scalars["Float"]["input"]>;
}>;
export type GetRunsLeaderboardQuery = {
@@ -9061,6 +9031,7 @@ export type GetUploadLinkMutation = {
};
stream?: {
__typename?: "UploadStreamGQL";
id: string;
uploadCompletionCursor: number;
} | null;
};
@@ -9159,6 +9130,7 @@ export type UploadStreamWithDetailsFragment = {
startTime?: any | null;
stream?: {
__typename?: "UploadStreamGQL";
id: string;
isCompleted: boolean;
lastIntendedSegmentBound?: number | null;
uploadCompletionCursor: number;
@@ -9183,6 +9155,7 @@ export type GetUploadStreamsWithDetailsQuery = {
startTime?: any | null;
stream?: {
__typename?: "UploadStreamGQL";
id: string;
isCompleted: boolean;
lastIntendedSegmentBound?: number | null;
uploadCompletionCursor: number;
@@ -9722,6 +9695,7 @@ export const UploadStreamWithDetailsFragmentDoc = gql`
name
startTime
stream {
id
isCompleted
lastIntendedSegmentBound
uploadCompletionCursor
@@ -11795,24 +11769,8 @@ export type GetVideoFeedQueryResult = Apollo.QueryResult<
GetVideoFeedQueryVariables
>;
export const GetMakesLeaderboardDocument = gql`
query GetMakesLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getMakesLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
query GetMakesLeaderboard($interval: TimeInterval, $when: DateTime) {
getMakesLeaderboard(interval: $interval, when: $when) {
entries {
user {
id
@@ -11841,11 +11799,6 @@ export const GetMakesLeaderboardDocument = gql`
* variables: {
* interval: // value for 'interval'
* when: // value for 'when'
* gameType: // value for 'gameType'
* tableSizeMin: // value for 'tableSizeMin'
* tableSizeMax: // value for 'tableSizeMax'
* pocketSizeMin: // value for 'pocketSizeMin'
* pocketSizeMax: // value for 'pocketSizeMax'
* },
* });
*/
@@ -11899,24 +11852,8 @@ export type GetMakesLeaderboardQueryResult = Apollo.QueryResult<
GetMakesLeaderboardQueryVariables
>;
export const GetRunsLeaderboardDocument = gql`
query GetRunsLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getLongestRunsLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
query GetRunsLeaderboard($interval: TimeInterval, $when: DateTime) {
getLongestRunsLeaderboard(interval: $interval, when: $when) {
entries {
id
runLength
@@ -11948,11 +11885,6 @@ export const GetRunsLeaderboardDocument = gql`
* variables: {
* interval: // value for 'interval'
* when: // value for 'when'
* gameType: // value for 'gameType'
* tableSizeMin: // value for 'tableSizeMin'
* tableSizeMax: // value for 'tableSizeMax'
* pocketSizeMin: // value for 'pocketSizeMin'
* pocketSizeMax: // value for 'pocketSizeMax'
* },
* });
*/
@@ -19547,6 +19479,7 @@ export const GetUploadLinkDocument = gql`
}
}
stream {
id
uploadCompletionCursor
}
}

View File

@@ -1,21 +1,5 @@
query GetMakesLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getMakesLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
query GetMakesLeaderboard($interval: TimeInterval, $when: DateTime) {
getMakesLeaderboard(interval: $interval, when: $when) {
entries {
user {
id
@@ -29,24 +13,8 @@ query GetMakesLeaderboard(
}
}
query GetRunsLeaderboard(
$interval: TimeInterval
$when: DateTime
$gameType: String
$tableSizeMin: Float
$tableSizeMax: Float
$pocketSizeMin: Float
$pocketSizeMax: Float
) {
getLongestRunsLeaderboard(
interval: $interval
when: $when
gameType: $gameType
tableSizeMin: $tableSizeMin
tableSizeMax: $tableSizeMax
pocketSizeMin: $pocketSizeMin
pocketSizeMax: $pocketSizeMax
) {
query GetRunsLeaderboard($interval: TimeInterval, $when: DateTime) {
getLongestRunsLeaderboard(interval: $interval, when: $when) {
entries {
id
runLength

View File

@@ -48,6 +48,7 @@ mutation GetUploadLink($videoId: Int!, $segmentIndex: Int!) {
}
}
stream {
id
uploadCompletionCursor
}
}
@@ -127,6 +128,7 @@ fragment UploadStreamWithDetails on VideoGQL {
name
startTime
stream {
id
isCompleted
lastIntendedSegmentBound
uploadCompletionCursor

File diff suppressed because it is too large Load Diff