@@ -26,7 +26,45 @@ export const DATASET_VERSIONS: DatasetVersion[] = [
2626 url : 'https://tessera-embeddings.s3.us-west-2.amazonaws.com/v1.1/cambridge.zarr' } ,
2727] ;
2828
29- export const catalogUrl = writable ( DATASET_VERSIONS [ 0 ] . url ) ;
29+ /** Query-string key carrying the active dataset, so the page URL is shareable.
30+ * Built-in stores use a short id (`?store=v1.1`); the default v1.0 omits the
31+ * param entirely; custom stores fall back to the full URL (`?store=<zarr url>`). */
32+ const STORE_PARAM = 'store' ;
33+
34+ /** Map an active store URL to its query-param value (null = omit the param). */
35+ function urlToStoreParam ( url : string ) : string | null {
36+ const version = DATASET_VERSIONS . find ( v => v . url === url ) ;
37+ if ( ! version ) return url ; // custom store → full URL
38+ if ( version . id === DATASET_VERSIONS [ 0 ] . id ) return null ; // default → clean URL
39+ return version . id ; // other built-ins → short id
40+ }
41+
42+ /** Resolve a query-param value back to a store URL (id shorthand or raw URL). */
43+ function storeParamToUrl ( param : string ) : string {
44+ return DATASET_VERSIONS . find ( v => v . id === param ) ?. url ?? param ;
45+ }
46+
47+ /** Read the initial store URL from the page query string, falling back to v1.0. */
48+ function readInitialStoreUrl ( ) : string {
49+ try {
50+ const param = new URLSearchParams ( window . location . search ) . get ( STORE_PARAM ) ;
51+ if ( param ) return storeParamToUrl ( param ) ;
52+ } catch { /* no window / malformed URL */ }
53+ return DATASET_VERSIONS [ 0 ] . url ;
54+ }
55+
56+ /** Reflect the active store into the page query string (replaceState, no nav). */
57+ function syncStoreUrlParam ( url : string ) : void {
58+ try {
59+ const u = new URL ( window . location . href ) ;
60+ const param = urlToStoreParam ( url ) ;
61+ if ( param === null ) u . searchParams . delete ( STORE_PARAM ) ;
62+ else u . searchParams . set ( STORE_PARAM , param ) ;
63+ window . history . replaceState ( null , '' , u . toString ( ) ) ;
64+ } catch { /* no window / malformed URL */ }
65+ }
66+
67+ export const catalogUrl = writable ( readInitialStoreUrl ( ) ) ;
3068export const catalogStatus = writable < 'idle' | 'loading' | 'loaded' | 'error' > ( 'idle' ) ;
3169export const catalogError = writable < string > ( '' ) ;
3270
@@ -66,6 +104,7 @@ export async function loadCatalog(url: string): Promise<void> {
66104 if ( ! trimmed ) return ;
67105
68106 catalogUrl . set ( trimmed ) ;
107+ syncStoreUrlParam ( trimmed ) ;
69108 catalogStatus . set ( 'loading' ) ;
70109 catalogError . set ( '' ) ;
71110 allZones . set ( [ ] ) ;
0 commit comments