mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 06:42:23 +00:00
Refuse a Data Library entry past the 64-entry cap before it registers
Add registered and switched on an entry before the selection was cut to its first 64, so a 65th was dropped from the selection but stayed on: Browse showed it as not added, share links left it out and Remove all missed it. Start-up registered a share's entries the same way past the cap. Add now refuses an entry a full library cannot keep, and start-up registers only what the selection keeps.
This commit is contained in:
1 parent
e25cce874d
commit
f33a6ada52
3 files changed
+72
-6
No files matched your search
@@ -9,6 +9,7 @@
|
||||
import { LIBRARY_ENTRIES, LIBRARY_LEDGER } from './catalog.js';
|
||||
import { libraryEntryIdOf, libraryLayerId } from './manifest.js';
|
||||
import {
|
||||
MAX_SELECTED,
|
||||
decodeLibraryParam,
|
||||
encodeLibraryParam,
|
||||
normalizeLibrarySelection,
|
||||
@@ -270,14 +271,17 @@ export function createDataLibrary({
|
||||
// link, it alone decides what is on, as it does for core layers, so a
|
||||
// share with every library entry off switches the stored ones off.
|
||||
// Added entries register even while off, so their rows show.
|
||||
for (const id of [...stored.added, ...(linked || [])]) {
|
||||
// Only what the selection keeps registers: past its cap an entry would
|
||||
// be a row the library no longer knows.
|
||||
const next = normalizeLibrarySelection(
|
||||
{ added: [...stored.added, ...(linked || [])], on: linked ?? stored.on },
|
||||
switchable,
|
||||
);
|
||||
for (const id of next.added) {
|
||||
const entry = byId.get(id);
|
||||
if (entry && addable(id)) register(entry);
|
||||
}
|
||||
applySelection(
|
||||
{ added: [...stored.added, ...(linked || [])], on: linked ?? stored.on },
|
||||
linked ? 'share-restore' : 'local-restore',
|
||||
);
|
||||
applySelection(next, linked ? 'share-restore' : 'local-restore');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,6 +291,9 @@ export function createDataLibrary({
|
||||
*/
|
||||
async function add(id) {
|
||||
if (destroyed || !addable(id) || pending.has(id)) return false;
|
||||
// A full library refuses the entry before its layer exists.
|
||||
if (!selection.added.includes(id) && selection.added.length >= MAX_SELECTED)
|
||||
return false;
|
||||
const entry = byId.get(id);
|
||||
const work = (async () => {
|
||||
if (!register(entry)) return false;
|
||||
|
||||
@@ -345,6 +345,64 @@ test('a share opened while an earlier one is still switching on wins', async (t)
|
||||
library.destroy();
|
||||
});
|
||||
|
||||
test('a full library refuses another entry before its layer exists', async (t) => {
|
||||
const many = validateLibraryCatalog(
|
||||
Array.from({ length: 66 }, (_, index) => tiles(`entry-${index}`)),
|
||||
).entries;
|
||||
const manyLedger = many.map(({ id }, index) => [
|
||||
id,
|
||||
index.toString(36).padStart(2, '0'),
|
||||
]);
|
||||
const availability = {
|
||||
async getAvailability() {
|
||||
return {
|
||||
server: true,
|
||||
availability: new Map(
|
||||
many.map(({ id }) => [id, { available: true, reason: null }]),
|
||||
),
|
||||
};
|
||||
},
|
||||
tileTemplate: (entry) => entry.source.url,
|
||||
};
|
||||
const full = JSON.stringify({
|
||||
added: many.slice(0, 64).map(({ id }) => id),
|
||||
on: [],
|
||||
});
|
||||
const manager = sealedManager(t);
|
||||
const library = createDataLibrary({
|
||||
entries: many,
|
||||
ledger: manyLedger,
|
||||
dataManager: manager,
|
||||
services: {},
|
||||
storage: memoryStorage(full),
|
||||
shareLink: fakeShareLink(null),
|
||||
source: availability,
|
||||
});
|
||||
await library.start();
|
||||
assert.equal(manager.layers.size, 64);
|
||||
assert.equal(await library.add('entry-64'), false);
|
||||
assert.equal(manager.layers.size, 64, 'no layer outside the selection');
|
||||
// A share into a full library adds no row the library cannot keep.
|
||||
const shared = sealedManager(t);
|
||||
const opened = createDataLibrary({
|
||||
entries: many,
|
||||
ledger: manyLedger,
|
||||
dataManager: shared,
|
||||
services: {},
|
||||
storage: memoryStorage(full),
|
||||
shareLink: fakeShareLink([manyLedger[65][1]]),
|
||||
source: availability,
|
||||
});
|
||||
await opened.start();
|
||||
assert.equal(shared.layers.has('lib-entry-65'), false);
|
||||
assert.equal(
|
||||
opened.list().filter((row) => row.added).length,
|
||||
shared.layers.size,
|
||||
);
|
||||
library.destroy();
|
||||
opened.destroy();
|
||||
});
|
||||
|
||||
test('zoom flies to an added layer through the caller, reset removes everything', async (t) => {
|
||||
const manager = sealedManager(t);
|
||||
const storage = memoryStorage();
|
||||
|
||||
@@ -12,7 +12,8 @@ import { LIBRARY_ID_PATTERN } from './manifest.js';
|
||||
export const LIBRARY_STORAGE_KEY = 'gev:library:v1';
|
||||
export const LIBRARY_SHARE_PARAM = 'lib';
|
||||
export const LIBRARY_TOKEN_PATTERN = /^[0-9a-z]{2}$/;
|
||||
const MAX_SELECTED = 64;
|
||||
/** The most entries one library (and one share link) holds. */
|
||||
export const MAX_SELECTED = 64;
|
||||
const MAX_PARAM_CHARS = 3 * MAX_SELECTED;
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user