Files
rrweb/packages/web-extension/src/utils/storage.ts
Arun Kunigiri 4277d7e9c3 Added session downloader for chrome extension (#1522)
* Added session downloader for chrome extension

- The session list now has a button to download sessions as .json files for use with rrweb-player
- Improved styling for the delete and download buttons
2026-04-01 12:00:00 +08:00

110 lines
3.1 KiB
TypeScript

import { openDB } from 'idb';
import type { eventWithTime } from '@rrweb/types';
import type { Session } from '~/types';
/**
* Storage related functions with indexedDB.
*/
const EventStoreName = 'events';
type EventData = {
id: string;
events: eventWithTime[];
};
export async function getEventStore() {
return openDB<EventData>(EventStoreName, 1, {
upgrade(db) {
db.createObjectStore(EventStoreName, {
keyPath: 'id',
autoIncrement: false,
});
},
});
}
export async function getEvents(id: string) {
const db = await getEventStore();
const data = (await db.get(EventStoreName, id)) as EventData;
return data.events;
}
const SessionStoreName = 'sessions';
export async function getSessionStore() {
return openDB<Session>(SessionStoreName, 1, {
upgrade(db) {
// Create a store of objects
db.createObjectStore(SessionStoreName, {
// The 'id' property of the object will be the key.
keyPath: 'id',
// If it isn't explicitly set, create a value by auto incrementing.
autoIncrement: false,
});
},
});
}
export async function saveSession(session: Session, events: eventWithTime[]) {
const eventStore = await getEventStore();
await eventStore.put(EventStoreName, { id: session.id, events });
const store = await getSessionStore();
await store.add(SessionStoreName, session);
}
export async function getSession(id: string) {
const store = await getSessionStore();
return store.get(SessionStoreName, id) as Promise<Session>;
}
export async function getAllSessions() {
const store = await getSessionStore();
const sessions = (await store.getAll(SessionStoreName)) as Session[];
return sessions.sort((a, b) => b.createTimestamp - a.createTimestamp);
}
export async function deleteSession(id: string) {
const eventStore = await getEventStore();
const sessionStore = await getSessionStore();
await Promise.all([
eventStore.delete(EventStoreName, id),
sessionStore.delete(SessionStoreName, id),
]);
}
export async function deleteSessions(ids: string[]) {
const eventStore = await getEventStore();
const sessionStore = await getSessionStore();
const eventTransition = eventStore.transaction(EventStoreName, 'readwrite');
const sessionTransition = sessionStore.transaction(
SessionStoreName,
'readwrite',
);
const promises = [];
for (const id of ids) {
promises.push(eventTransition.store.delete(id));
promises.push(sessionTransition.store.delete(id));
}
await Promise.all(promises).then(() => {
return Promise.all([eventTransition.done, sessionTransition.done]);
});
}
export async function downloadSessions(ids: string[]) {
for (const sessionId of ids) {
const events = await getEvents(sessionId);
const session = await getSession(sessionId);
const blob = new Blob([JSON.stringify({ session, events }, null, 2)], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${session.name}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
}