diff --git a/src/library/controller.js b/src/library/controller.js index fffafb1f2..6be6d29ca 100644 --- a/src/library/controller.js +++ b/src/library/controller.js @@ -257,10 +257,16 @@ export function createDataLibrary({ } shareLink?.setLibraryShareListener?.(applyShare); + // The URL carries what is on. Until availability loads (or when it never + // does) that is still what the page opened with, so a hash write in the + // meantime keeps it; an entry this instance cannot serve stays in it too. shareLink?.setLibraryParamsEncoder?.((params) => encodeLibraryParam( params, - selection.on.filter((id) => isRegistered(id)), + loaded + ? selection.on + : ((queuedShare ? idsForTokens(queuedShare) : openingShare()) ?? + readStoredLibrarySelection(storage, switchable).on), tokens.tokenById, ), ); diff --git a/src/library/controller.test.mjs b/src/library/controller.test.mjs index 9aac21764..51daf7f2a 100644 --- a/src/library/controller.test.mjs +++ b/src/library/controller.test.mjs @@ -480,6 +480,40 @@ test('a layer that fails to tear down stays in the library', async (t) => { library.destroy(); }); +test('the URL keeps the opening lib= before availability loads and for entries it cannot serve', async (t) => { + const manager = sealedManager(t); + const shareLink = shareLinkDouble(); + let answer; + const pending = new Promise((resolve) => { + answer = resolve; + }); + const library = createDataLibrary({ + entries, + ledger, + dataManager: manager, + services: {}, + storage: memoryStorage(), + shareLink, + initialHash: '#lat=1&lon=2&lib=00.01', + source: { ...source({}), getAvailability: () => pending }, + }); + const started = library.start(); + // A camera move rewrites the hash before the catalog answers. + assert.equal(shareLink.encode(), '00.01'); + answer({ + server: false, + availability: new Map([ + ['night-lights', { available: false, reason: 'server-unavailable' }], + ['sea-marks', { available: true, reason: null }], + ]), + }); + await started; + await manager.waitForLayerSettled?.('lib-sea-marks'); + assert.equal(manager.layers.has('lib-night-lights'), false); + assert.equal(shareLink.encode(), '00.01'); + library.destroy(); +}); + test('zoom flies to an added layer through the caller, reset removes everything', async (t) => { const manager = sealedManager(t); const storage = memoryStorage();