Keep lib= in the URL before the library starts and for entries it cannot serve

The share encoder wrote only registered entries. Until availability
loaded nothing was registered, so any hash write in the meantime (a
camera move during start-up) deleted lib= from the address bar, and an
entry this instance could not serve (its proxy unreachable) was dropped
for good: copying the link or reloading lost those entries. The URL now
carries what the page opened with until the library starts, and every
entry that is on afterwards, served here or not.
This commit is contained in:
Sameh Khamis committed 2026-11-12 15:59:14 -08:00
1 parent 2d5db9f63d
commit 8d90cac7dc
2 files changed
+41 -1

No files matched your search

+7 -1
View File
@@ -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,
),
);
+34
View File
@@ -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();