Skip to content

Commit

Permalink
Prevent usage of more than ~1MB of session storage for history state
Browse files Browse the repository at this point in the history
  • Loading branch information
gitbugr committed Oct 6, 2024
1 parent 6179bbb commit 4d7d6f9
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions packages/core/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class Router {
protected navigationType?: string
protected activeVisit?: ActiveVisit
protected visitId: VisitId = null
protected sessionSize: number = 0;

public init({
initialPage,
Expand Down Expand Up @@ -509,25 +510,43 @@ export class Router {

private _pushState(page: Page): void {
const uniqueId = this.getStateId();
window.sessionStorage.setItem(uniqueId, JSON.stringify(page));
this.dropOldestStateItemToPreventQuotaExceeded();
const serializedPage = JSON.stringify(page);
window.sessionStorage.setItem(uniqueId, serializedPage);
window.history.pushState({_id: uniqueId}, '', page.url);
this.sessionSize += (new Blob([serializedPage])).size;
}

protected getAllStates(): string[] {
protected getAllStateIds(): string[] {
return JSON.parse(window.sessionStorage.getItem(allStateIdsSessionStorageKey) ?? '[]');
}

protected dropOldestStateItemToPreventQuotaExceeded() {
// Ensures inertia uses at most ~1M (+/- size of 1 Page) of session storage for history state
if (this.sessionSize > 1000000) {
const allStateIds = this.getAllStateIds();
const oldestStateId = allStateIds.shift();
if (oldestStateId) {
const sizeOfStateItem = new Blob([window.sessionStorage.getItem(oldestStateId) ?? '']).size;
window.sessionStorage.removeItem(oldestStateId);
window.sessionStorage.setItem(allStateIdsSessionStorageKey, JSON.stringify(allStateIds));
this.sessionSize -= sizeOfStateItem;
}
}
}

private getStateId() {
const newId = `inertia_${Date.now() + Math.floor(Math.random() * 1000)}`;
window.sessionStorage.setItem(allStateIdsSessionStorageKey, JSON.stringify([...this.getAllStates(), newId]));
window.sessionStorage.setItem(allStateIdsSessionStorageKey, JSON.stringify([...this.getAllStateIds(), newId]));
return newId;
}

public clearHistory(): void {
this.getAllStates().forEach((id) => {
this.getAllStateIds().forEach((id) => {
window.sessionStorage.removeItem(id);
});
window.sessionStorage.removeItem(allStateIdsSessionStorageKey);
this.sessionSize = 0;
}

protected pushState(page: Page): void {
Expand All @@ -543,8 +562,11 @@ export class Router {

private _replaceState(page: Page): void {
const currentId = window.history.state?._id ?? this.getStateId();
window.sessionStorage.setItem(currentId, JSON.stringify(page));
const serializedPage = JSON.stringify(page);
this.sessionSize -= (new Blob([window.sessionStorage.getItem(currentId) ?? ''])).size;
window.sessionStorage.setItem(currentId, serializedPage);
window.history.replaceState({_id: currentId}, '', page.url);
this.sessionSize += (new Blob([serializedPage])).size;
}

protected replaceState(page: Page): void {
Expand Down

0 comments on commit 4d7d6f9

Please sign in to comment.