@@ -53,11 +53,23 @@ import {
5353 formatInteger ,
5454 formatToDisplayName ,
5555} from "@thunderstore/cyberstorm/src/utils/utils" ;
56- import { DapperTs } from "@thunderstore/dapper-ts" ;
57- import { getPackageVersionDetails } from "@thunderstore/dapper-ts/src/methods/packageVersion" ;
56+ import { type OutletContextShape } from "~/root" ;
57+ import { CopyButton } from "~/commonComponents/CopyButton/CopyButton" ;
58+ import { getPublicEnvVariables } from "cyberstorm/security/publicEnvVariables" ;
5859import { getTeamDetails } from "@thunderstore/dapper-ts/src/methods/team" ;
60+ import { isPromise } from "cyberstorm/utils/typeChecks" ;
61+ import { getPackageVersionDetails } from "@thunderstore/dapper-ts/src/methods/packageVersion" ;
62+ import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
63+ import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError" ;
64+ import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings" ;
65+ import { getLoaderTools } from "cyberstorm/utils/getLoaderTools" ;
5966
60- import "./packageListing.css" ;
67+ const packageVersionNotFoundMappings = [
68+ createNotFoundMapping (
69+ "Package version not found." ,
70+ "We could not find the requested package version."
71+ ) ,
72+ ] ;
6173
6274export async function loader ( { params } : LoaderFunctionArgs ) {
6375 if (
@@ -66,55 +78,81 @@ export async function loader({ params }: LoaderFunctionArgs) {
6678 params . packageId &&
6779 params . packageVersion
6880 ) {
69- const publicEnvVariables = getPublicEnvVariables ( [ "VITE_API_URL" ] ) ;
70- const dapper = new DapperTs ( ( ) => {
81+ const { dapper } = getLoaderTools ( ) ;
82+ try {
83+ const [ community , version , team ] = await Promise . all ( [
84+ dapper . getCommunity ( params . communityId ) ,
85+ dapper . getPackageVersionDetails (
86+ params . namespaceId ,
87+ params . packageId ,
88+ params . packageVersion
89+ ) ,
90+ dapper . getTeamDetails ( params . namespaceId ) ,
91+ ] ) ;
92+
7193 return {
72- apiHost : publicEnvVariables . VITE_API_URL ,
73- sessionId : undefined ,
94+ communityId : params . communityId ,
95+ community,
96+ version,
97+ team,
7498 } ;
75- } ) ;
76-
77- return {
78- communityId : params . communityId ,
79- community : await dapper . getCommunity ( params . communityId ) ,
80- version : await dapper . getPackageVersionDetails (
81- params . namespaceId ,
82- params . packageId ,
83- params . packageVersion
84- ) ,
85- team : await dapper . getTeamDetails ( params . namespaceId ) ,
86- } ;
99+ } catch ( error ) {
100+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } ) ;
101+ }
87102 }
88- throw new Response ( "Package not found" , { status : 404 } ) ;
103+ throwUserFacingPayloadResponse ( {
104+ headline : "Package not found." ,
105+ description : "We could not find the requested package." ,
106+ category : "not_found" ,
107+ status : 404 ,
108+ } ) ;
89109}
90110
91- export async function clientLoader ( { params } : LoaderFunctionArgs ) {
111+ export function clientLoader ( { params } : LoaderFunctionArgs ) {
92112 if (
93113 params . communityId &&
94114 params . namespaceId &&
95115 params . packageId &&
96116 params . packageVersion
97117 ) {
98- const tools = getSessionTools ( ) ;
99- const dapper = new DapperTs ( ( ) => {
100- return {
101- apiHost : tools ?. getConfig ( ) . apiHost ,
102- sessionId : tools ?. getConfig ( ) . sessionId ,
103- } ;
104- } ) ;
105-
106- return {
107- communityId : params . communityId ,
108- community : dapper . getCommunity ( params . communityId ) ,
109- version : dapper . getPackageVersionDetails (
118+ const { dapper } = getLoaderTools ( ) ;
119+ const community = dapper
120+ . getCommunity ( params . communityId )
121+ . catch ( ( error ) =>
122+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
123+ ) ;
124+ const version = dapper
125+ . getPackageVersionDetails (
110126 params . namespaceId ,
111127 params . packageId ,
112128 params . packageVersion
113- ) ,
114- team : dapper . getTeamDetails ( params . namespaceId ) ,
129+ )
130+ . catch ( ( error ) =>
131+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
132+ ) ;
133+ const team = dapper
134+ . getTeamDetails ( params . namespaceId )
135+ . catch ( ( error ) =>
136+ handleLoaderError ( error , { mappings : packageVersionNotFoundMappings } )
137+ ) ;
138+
139+ return {
140+ communityId : params . communityId ,
141+ community,
142+ version,
143+ team,
115144 } ;
116145 }
117- throw new Response ( "Package not found" , { status : 404 } ) ;
146+ throwUserFacingPayloadResponse ( {
147+ headline : "Package not found." ,
148+ description : "We could not find the requested package." ,
149+ category : "not_found" ,
150+ status : 404 ,
151+ } ) ;
152+ }
153+
154+ export function ErrorBoundary ( ) {
155+ return < NimbusDefaultRouteErrorBoundary /> ;
118156}
119157
120158export function shouldRevalidate ( arg : ShouldRevalidateFunctionArgs ) {
@@ -154,39 +192,65 @@ export default function PackageVersion() {
154192 // If strict mode is removed from the entry.client.tsx, this should only run once
155193 useEffect ( ( ) => {
156194 if ( ! startsHydrated . current && isHydrated ) return ;
157- if ( isPromise ( version ) ) {
158- version . then ( ( versionData ) => {
159- setFirstUploaded (
160- < RelativeTime
161- time = { versionData . datetime_created }
162- suppressHydrationWarning
163- />
164- ) ;
165- } ) ;
166- } else {
195+ if ( ! isPromise ( version ) ) {
167196 setFirstUploaded (
168197 < RelativeTime
169198 time = { version . datetime_created }
170199 suppressHydrationWarning
171200 />
172201 ) ;
202+ return ;
173203 }
174- } , [ ] ) ;
204+
205+ let isCancelled = false ;
206+
207+ const resolveVersionTimes = async ( ) => {
208+ try {
209+ const versionData = await version ;
210+ if ( isCancelled ) {
211+ return ;
212+ }
213+
214+ setFirstUploaded (
215+ < RelativeTime
216+ time = { versionData . datetime_created }
217+ suppressHydrationWarning
218+ />
219+ ) ;
220+ } catch ( error ) {
221+ if ( ! isCancelled ) {
222+ console . error ( "Failed to resolve version metadata" , error ) ;
223+ }
224+ }
225+ } ;
226+
227+ resolveVersionTimes ( ) ;
228+
229+ return ( ) => {
230+ isCancelled = true ;
231+ } ;
232+ } , [ isHydrated , version ] ) ;
175233 // END: For sidebar meta dates
176234
177235 const currentTab = location . pathname . split ( "/" ) [ 8 ] || "details" ;
178236
179237 const versionAndCommunityPromise = useMemo (
180238 ( ) => Promise . all ( [ version , community ] ) ,
181- [ ]
239+ [ version , community ]
182240 ) ;
183241
184- const versionAndTeamPromise = useMemo ( ( ) => Promise . all ( [ version , team ] ) , [ ] ) ;
242+ const versionAndTeamPromise = useMemo (
243+ ( ) => Promise . all ( [ version , team ] ) ,
244+ [ version , team ]
245+ ) ;
185246
186247 return (
187248 < >
188249 < Suspense >
189- < Await resolve = { versionAndCommunityPromise } >
250+ < Await
251+ resolve = { versionAndCommunityPromise }
252+ errorElement = { < NimbusAwaitErrorElement /> }
253+ >
190254 { ( resolvedValue ) => (
191255 < >
192256 < meta
@@ -235,7 +299,10 @@ export default function PackageVersion() {
235299 </ NewAlert >
236300 }
237301 >
238- < Await resolve = { version } >
302+ < Await
303+ resolve = { version }
304+ errorElement = { < NimbusAwaitErrorElement /> }
305+ >
239306 { ( resolvedValue ) => (
240307 < NewAlert csVariant = "warning" >
241308 You are viewing a potentially older version of this
@@ -259,7 +326,10 @@ export default function PackageVersion() {
259326 < SkeletonBox className = "package-listing__page-header-skeleton" />
260327 }
261328 >
262- < Await resolve = { version } >
329+ < Await
330+ resolve = { version }
331+ errorElement = { < NimbusAwaitErrorElement /> }
332+ >
263333 { ( resolvedValue ) => (
264334 < PageHeader
265335 headingLevel = "1"
@@ -325,15 +395,21 @@ export default function PackageVersion() {
325395 rootClasses = "package-listing__drawer"
326396 >
327397 < Suspense fallback = { < p > Loading...</ p > } >
328- < Await resolve = { version } >
398+ < Await
399+ resolve = { version }
400+ errorElement = { < NimbusAwaitErrorElement /> }
401+ >
329402 { ( resolvedValue ) => (
330403 < > { packageMeta ( firstUploaded , resolvedValue ) } </ >
331404 ) }
332405 </ Await >
333406 </ Suspense >
334407 </ Drawer >
335408 < Suspense fallback = { < p > Loading...</ p > } >
336- < Await resolve = { versionAndTeamPromise } >
409+ < Await
410+ resolve = { versionAndTeamPromise }
411+ errorElement = { < NimbusAwaitErrorElement /> }
412+ >
337413 { ( resolvedValue ) => (
338414 < Actions
339415 team = { resolvedValue [ 1 ] }
@@ -348,7 +424,10 @@ export default function PackageVersion() {
348424 < SkeletonBox className = "package-listing__nav-skeleton" />
349425 }
350426 >
351- < Await resolve = { version } >
427+ < Await
428+ resolve = { version }
429+ errorElement = { < NimbusAwaitErrorElement /> }
430+ >
352431 { ( resolvedValue ) => (
353432 < >
354433 < Tabs >
@@ -418,7 +497,10 @@ export default function PackageVersion() {
418497 < SkeletonBox className = "package-listing-sidebar__install-skeleton" />
419498 }
420499 >
421- < Await resolve = { version } >
500+ < Await
501+ resolve = { version }
502+ errorElement = { < NimbusAwaitErrorElement /> }
503+ >
422504 { ( resolvedValue ) => (
423505 < NewButton
424506 csVariant = "accent"
@@ -442,7 +524,10 @@ export default function PackageVersion() {
442524 < SkeletonBox className = "package-listing-sidebar__actions-skeleton" />
443525 }
444526 >
445- < Await resolve = { versionAndTeamPromise } >
527+ < Await
528+ resolve = { versionAndTeamPromise }
529+ errorElement = { < NimbusAwaitErrorElement /> }
530+ >
446531 { ( resolvedValue ) => (
447532 < Actions
448533 team = { resolvedValue [ 1 ] }
@@ -456,7 +541,10 @@ export default function PackageVersion() {
456541 < SkeletonBox className = "package-listing-sidebar__skeleton" />
457542 }
458543 >
459- < Await resolve = { version } >
544+ < Await
545+ resolve = { version }
546+ errorElement = { < NimbusAwaitErrorElement /> }
547+ >
460548 { ( resolvedValue ) => (
461549 < > { packageMeta ( firstUploaded , resolvedValue ) } </ >
462550 ) }
0 commit comments