1- import { useAtomValue } from "@effect/atom-react" ;
1+ import { useAtomMount , useAtomSubscribe , useAtomValue } from "@effect/atom-react" ;
22import { resolveFilesystemReadAccess } from "@t3tools/client-runtime/state/filesystem" ;
33import {
44 assetUrlStateFromResult ,
@@ -13,6 +13,7 @@ import * as Effect from "effect/Effect";
1313import { Atom , AsyncResult } from "effect/reactivity" ;
1414import { useCallback } from "react" ;
1515
16+ import { environmentCatalog } from "../connection/catalog" ;
1617import { connectionAtomRuntime } from "../connection/runtime" ;
1718import { projectFaviconDatabaseCache } from "../lib/projectFaviconDatabaseCache" ;
1819import { type AssetUrlState , deriveAssetUrlState } from "./asset-url-state" ;
@@ -112,7 +113,7 @@ export async function refreshAssetUrl(
112113 reportFailure : false ,
113114 ...( signal ? { signal } : { } ) ,
114115 } ) ;
115- // The query can wait through a reconnect ; resolve against the connection that answered it .
116+ // A route can change while the query runs ; resolve against the connection now current .
116117 const connection = appAtomRegistry . get ( connectionAtom ) ;
117118 if ( connection . _tag === "None" ) return null ;
118119 const state = assetUrlStateFromResult ( result , connection . value . httpBaseUrl ) ;
@@ -154,6 +155,7 @@ const freshAssetUrlFamily = Atom.family((key: FreshAssetUrlKey) =>
154155const noFreshAssetUrl = Atom . make ( AsyncResult . initial < AuthorizedAssetUrl , Error > ( ) ) . pipe (
155156 Atom . withLabel ( "fresh-asset-url:none" ) ,
156157) ;
158+ const noSessionGeneration = Atom . make ( 0 ) ;
157159
158160/**
159161 * A signed URL minted when the reader mounts, not a cached one: cached links can
@@ -166,9 +168,20 @@ export function useFreshAssetUrl(
166168) : AsyncResult . AsyncResult < AuthorizedAssetUrl , Error > {
167169 const connection = usePreparedConnection ( environmentId ) ;
168170 const httpBaseUrl = connection . _tag === "Some" ? connection . value . httpBaseUrl : null ;
169- return useAtomValue (
171+ const atom =
170172 resource === null
171173 ? noFreshAssetUrl
172- : freshAssetUrlFamily ( { environmentId, resource, httpBaseUrl, revision } ) ,
173- ) ;
174+ : freshAssetUrlFamily ( { environmentId, resource, httpBaseUrl, revision } ) ;
175+ // Minting fails at once while the environment is unreachable; mint again once a new session is
176+ // up instead of keeping the error until Retry.
177+ const sessionGeneration =
178+ environmentId === null
179+ ? noSessionGeneration
180+ : environmentCatalog . sessionGenerationAtom ( environmentId ) ;
181+ // A listener alone does not compute the atom, so nothing would follow the connection.
182+ useAtomMount ( sessionGeneration ) ;
183+ useAtomSubscribe ( sessionGeneration , ( ) => {
184+ if ( AsyncResult . isFailure ( appAtomRegistry . get ( atom ) ) ) appAtomRegistry . refresh ( atom ) ;
185+ } ) ;
186+ return useAtomValue ( atom ) ;
174187}
0 commit comments