diff --git a/src/library/controller.js b/src/library/controller.js index 9fdecd041..200bbd07e 100644 --- a/src/library/controller.js +++ b/src/library/controller.js @@ -388,8 +388,19 @@ export function createDataLibrary({ if ( isRegistered(id) && !(await dataManager.unregisterLibraryLayer(libraryLayerId(id))) - ) + ) { + // Switched off before teardown failed: it is no longer on, so the + // link and what is remembered must not say it is. + if (!dataManager.isEnabled?.(libraryLayerId(id))) { + selection = { + ...selection, + on: selection.on.filter((other) => other !== id), + }; + savedOn = savedOn.filter((other) => other !== id); + persist(); + } return false; + } selection = { added: selection.added.filter((other) => other !== id), on: selection.on.filter((other) => other !== id), diff --git a/src/library/controller.test.mjs b/src/library/controller.test.mjs index 46bed73ca..970d6c54c 100644 --- a/src/library/controller.test.mjs +++ b/src/library/controller.test.mjs @@ -581,6 +581,41 @@ test('the URL keeps the opening lib= before availability loads and for entries i library.destroy(); }); +test('a layer switched off before its teardown failed is no longer shared as on', async (t) => { + const manager = sealedManager(t); + const storage = memoryStorage(); + const shareLink = shareLinkDouble(); + const library = createDataLibrary({ + entries, + ledger, + dataManager: manager, + services: {}, + storage, + shareLink, + initialHash: '', + source: source({}), + }); + await library.start(); + await library.add('night-lights'); + assert.equal(shareLink.encode(), '00'); + const { module } = manager.layers.get('lib-night-lights'); + const destroy = module.destroy; + module.destroy = async () => { + throw new Error('stuck'); + }; + t.mock.method(console, 'warn', () => {}); + try { + assert.equal(await library.remove('night-lights'), false); + assert.equal(manager.isEnabled('lib-night-lights'), false); + assert.equal(shareLink.encode(), null); + const saved = JSON.parse(storage.store.get(LIBRARY_STORAGE_KEY)); + assert.deepEqual(saved, { added: ['night-lights'], on: [] }); + } finally { + module.destroy = destroy; + } + library.destroy(); +}); + test('zoom flies to an added layer through the caller, reset removes everything', async (t) => { const manager = sealedManager(t); const storage = memoryStorage();