Skip to content

Commit bd852b8

Browse files
committed
client: nicer session storage surface
1 parent 38d74cf commit bd852b8

File tree

1 file changed

+106
-19
lines changed

1 file changed

+106
-19
lines changed

src/static/js/client.js

+106-19
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,117 @@ function initInfo(infoKey, description) {
4343
}
4444

4545
if (object.session) {
46-
const sessionDefaults = object.session;
46+
const sessionSpecs = object.session;
4747

4848
object.session = {};
4949

50-
for (const [key, defaultValue] of Object.entries(sessionDefaults)) {
50+
for (const [key, spec] of Object.entries(sessionSpecs)) {
51+
const hasSpec =
52+
typeof spec === 'object' && spec !== null;
53+
54+
const defaultValue =
55+
(hasSpec
56+
? spec.default ?? null
57+
: spec);
58+
59+
let formatRead = value => value;
60+
let formatWrite = value => value;
61+
if (hasSpec && spec.type) {
62+
switch (spec.type) {
63+
case 'number':
64+
formatRead = parseFloat;
65+
formatWrite = String;
66+
break;
67+
68+
case 'boolean':
69+
formatRead = Boolean;
70+
formatWrite = String;
71+
break;
72+
73+
case 'string':
74+
formatRead = String;
75+
formatWrite = String;
76+
break;
77+
78+
case 'json':
79+
formatRead = JSON.parse;
80+
formatWrite = JSON.stringify;
81+
break;
82+
83+
default:
84+
throw new Error(`Unknown type for session storage spec "${spec.type}"`);
85+
}
86+
}
87+
88+
let getMaxLength =
89+
(!hasSpec
90+
? () => Infinity
91+
: typeof spec.maxLength === 'function'
92+
? (object.settings
93+
? () => spec.maxLength(object.settings)
94+
: () => spec.maxLength())
95+
: () => spec.maxLength);
96+
5197
const storageKey = `hsmusic.${infoKey}.${key}`;
5298

5399
let fallbackValue = defaultValue;
54100

55101
Object.defineProperty(object.session, key, {
56102
get: () => {
103+
let value;
57104
try {
58-
return sessionStorage.getItem(storageKey) ?? defaultValue;
105+
value = sessionStorage.getItem(storageKey) ?? defaultValue;
59106
} catch (error) {
60107
if (error instanceof DOMException) {
61-
return fallbackValue;
108+
value = fallbackValue;
62109
} else {
63110
throw error;
64111
}
65112
}
113+
114+
if (value === null) {
115+
return null;
116+
}
117+
118+
return formatRead(value);
66119
},
67120

68121
set: (value) => {
122+
if (value !== null && value !== '') {
123+
value = formatWrite(value);
124+
}
125+
126+
if (value === null) {
127+
value = '';
128+
}
129+
130+
const maxLength = getMaxLength();
131+
if (value.length > maxLength) {
132+
console.warn(
133+
`Requested to set session storage ${storageKey} ` +
134+
`beyond maximum length ${maxLength}, ` +
135+
`ignoring this value.`);
136+
console.trace();
137+
return;
138+
}
139+
140+
let operation;
141+
if (value === '') {
142+
fallbackValue = null;
143+
operation = () => {
144+
sessionStorage.removeItem(storageKey);
145+
};
146+
} else {
147+
fallbackValue = value;
148+
operation = () => {
149+
sessionStorage.setItem(storageKey, value);
150+
};
151+
}
152+
69153
try {
70-
sessionStorage.setItem(storageKey, value);
154+
operation();
71155
} catch (error) {
72-
if (error instanceof DOMException) {
73-
fallbackValue = value;
74-
} else {
156+
if (!(error instanceof DOMException)) {
75157
throw error;
76158
}
77159
}
@@ -3723,10 +3805,19 @@ const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
37233805
},
37243806

37253807
session: {
3726-
activeQuery: null,
3727-
activeQueryResults: null,
3808+
activeQuery: {
3809+
type: 'string',
3810+
},
37283811

3729-
repeatQueryOnReload: false,
3812+
activeQueryResults: {
3813+
type: 'json',
3814+
maxLength: settings => settings.maxActiveResultsStorage,
3815+
},
3816+
3817+
repeatQueryOnReload: {
3818+
type: 'boolean',
3819+
default: false,
3820+
},
37303821
},
37313822

37323823
settings: {
@@ -3978,7 +4069,7 @@ function initializeSidebarSearchState() {
39784069
if (session.repeatQueryOnReload) {
39794070
activateSidebarSearch(session.activeQuery);
39804071
} else if (session.activeQueryResults) {
3981-
showSidebarSearchResults(JSON.parse(session.activeQueryResults));
4072+
showSidebarSearchResults(session.activeQueryResults);
39824073
}
39834074
}
39844075
}
@@ -4063,11 +4154,7 @@ async function activateSidebarSearch(query) {
40634154
updateSidebarSearchStatus();
40644155

40654156
session.activeQuery = query;
4066-
4067-
const stringifiedResults = JSON.stringify(results);
4068-
if (stringifiedResults.length < settings.maxActiveResultsStorage) {
4069-
session.activeQueryResults = JSON.stringify(results);
4070-
}
4157+
session.activeQueryResults = results;
40714158

40724159
showSidebarSearchResults(results);
40734160
}
@@ -4088,8 +4175,8 @@ function clearSidebarSearch() {
40884175

40894176
state.searchStage = null;
40904177

4091-
session.activeQuery = '';
4092-
session.activeQueryResults = '';
4178+
session.activeQuery = null;
4179+
session.activeQueryResults = null;
40934180

40944181
hideSidebarSearchResults();
40954182
}

0 commit comments

Comments
 (0)