mostly formatting, dependency fix
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import React, { forwardRef, useImperativeHandle } from "react";
|
||||
import { act, render } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { PageRef } from "../pdf/pdfTypes";
|
||||
import React, { forwardRef, useImperativeHandle } from 'react';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import type { PageRef } from '../pdf/pdfTypes';
|
||||
import type {
|
||||
WorkspaceCommandRecord,
|
||||
WorkspaceCommandState,
|
||||
} from "./workspaceCommands";
|
||||
import { useWorkspaceState } from "./useWorkspaceState";
|
||||
} from './workspaceCommands';
|
||||
import { useWorkspaceState } from './useWorkspaceState';
|
||||
|
||||
function page(id: string, sourcePageIndex: number, rotation = 0): PageRef {
|
||||
return { id, sourcePageIndex, rotation };
|
||||
@@ -15,7 +15,7 @@ function page(id: string, sourcePageIndex: number, rotation = 0): PageRef {
|
||||
function state(
|
||||
pages: PageRef[],
|
||||
selectedPageIds: string[] = [],
|
||||
lastSelectedVisualIndex: number | null = null,
|
||||
lastSelectedVisualIndex: number | null = null
|
||||
): WorkspaceCommandState {
|
||||
return { pages, selectedPageIds, lastSelectedVisualIndex };
|
||||
}
|
||||
@@ -32,18 +32,18 @@ interface HarnessRef {
|
||||
};
|
||||
replaceWorkspaceState: ReturnType<
|
||||
typeof useWorkspaceState
|
||||
>["replaceWorkspaceState"];
|
||||
>['replaceWorkspaceState'];
|
||||
getCurrentCommandState: ReturnType<
|
||||
typeof useWorkspaceState
|
||||
>["getCurrentCommandState"];
|
||||
>['getCurrentCommandState'];
|
||||
createWorkspaceCommand: ReturnType<
|
||||
typeof useWorkspaceState
|
||||
>["createWorkspaceCommand"];
|
||||
>['createWorkspaceCommand'];
|
||||
executeWorkspaceCommand: ReturnType<
|
||||
typeof useWorkspaceState
|
||||
>["executeWorkspaceCommand"];
|
||||
handleUndo: ReturnType<typeof useWorkspaceState>["handleUndo"];
|
||||
handleRedo: ReturnType<typeof useWorkspaceState>["handleRedo"];
|
||||
>['executeWorkspaceCommand'];
|
||||
handleUndo: ReturnType<typeof useWorkspaceState>['handleUndo'];
|
||||
handleRedo: ReturnType<typeof useWorkspaceState>['handleRedo'];
|
||||
}
|
||||
|
||||
const Harness = forwardRef<HarnessRef, { onContentChanged?: () => void }>(
|
||||
@@ -69,7 +69,7 @@ const Harness = forwardRef<HarnessRef, { onContentChanged?: () => void }>(
|
||||
}));
|
||||
|
||||
return null;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function renderHarness(onContentChanged = vi.fn()) {
|
||||
@@ -77,54 +77,54 @@ function renderHarness(onContentChanged = vi.fn()) {
|
||||
render(<Harness ref={ref} onContentChanged={onContentChanged} />);
|
||||
|
||||
if (!ref.current) {
|
||||
throw new Error("Harness ref was not initialized");
|
||||
throw new Error('Harness ref was not initialized');
|
||||
}
|
||||
|
||||
return { ref, onContentChanged };
|
||||
}
|
||||
|
||||
describe("useWorkspaceState", () => {
|
||||
it("replaces workspace state from loaded data without marking it dirty", () => {
|
||||
describe('useWorkspaceState', () => {
|
||||
it('replaces workspace state from loaded data without marking it dirty', () => {
|
||||
const { ref } = renderHarness();
|
||||
const loadedPages = [page("p1", 0), page("p2", 1, 90)];
|
||||
const loadedPages = [page('p1', 0), page('p2', 1, 90)];
|
||||
|
||||
act(() => {
|
||||
ref.current?.replaceWorkspaceState({
|
||||
pages: loadedPages,
|
||||
selectedPageIds: ["p2"],
|
||||
selectedPageIds: ['p2'],
|
||||
lastSelectedVisualIndex: 1,
|
||||
history: [],
|
||||
redoHistory: [],
|
||||
dirty: false,
|
||||
message: "Workspace loaded.",
|
||||
message: 'Workspace loaded.',
|
||||
});
|
||||
});
|
||||
|
||||
expect(ref.current?.snapshot()).toMatchObject({
|
||||
pages: loadedPages,
|
||||
selectedPageIds: ["p2"],
|
||||
selectedPageIds: ['p2'],
|
||||
lastSelectedVisualIndex: 1,
|
||||
workspaceDirty: false,
|
||||
workspaceMessage: "Workspace loaded.",
|
||||
workspaceMessage: 'Workspace loaded.',
|
||||
workspaceHistory: [],
|
||||
redoHistory: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("executes commands, stores history, clears redo, and marks content changed", () => {
|
||||
it('executes commands, stores history, clears redo, and marks content changed', () => {
|
||||
const { ref, onContentChanged } = renderHarness();
|
||||
const before = state([page("p1", 0), page("p2", 1)], ["p1"], 0);
|
||||
const after = state([page("p2", 1), page("p1", 0)], ["p2"], 0);
|
||||
const before = state([page('p1', 0), page('p2', 1)], ['p1'], 0);
|
||||
const after = state([page('p2', 1), page('p1', 0)], ['p2'], 0);
|
||||
|
||||
act(() => {
|
||||
ref.current?.replaceWorkspaceState({
|
||||
...before,
|
||||
redoHistory: [
|
||||
{
|
||||
id: "redo-record",
|
||||
type: "old-redo",
|
||||
label: "Old redo",
|
||||
timestamp: "2026-05-17T10:00:00.000Z",
|
||||
id: 'redo-record',
|
||||
type: 'old-redo',
|
||||
label: 'Old redo',
|
||||
timestamp: '2026-05-17T10:00:00.000Z',
|
||||
payload: { before, after },
|
||||
},
|
||||
],
|
||||
@@ -133,34 +133,34 @@ describe("useWorkspaceState", () => {
|
||||
|
||||
act(() => {
|
||||
const command = ref.current?.createWorkspaceCommand({
|
||||
type: "reorder-pages",
|
||||
label: "Move page 2 before page 1",
|
||||
type: 'reorder-pages',
|
||||
label: 'Move page 2 before page 1',
|
||||
before,
|
||||
after,
|
||||
});
|
||||
|
||||
if (!command) throw new Error("Command was not created");
|
||||
if (!command) throw new Error('Command was not created');
|
||||
ref.current?.executeWorkspaceCommand(command);
|
||||
});
|
||||
|
||||
const snapshot = ref.current?.snapshot();
|
||||
expect(snapshot?.pages).toEqual(after.pages);
|
||||
expect(snapshot?.selectedPageIds).toEqual(["p2"]);
|
||||
expect(snapshot?.selectedPageIds).toEqual(['p2']);
|
||||
expect(snapshot?.workspaceDirty).toBe(true);
|
||||
expect(snapshot?.workspaceMessage).toBeNull();
|
||||
expect(snapshot?.workspaceHistory).toHaveLength(1);
|
||||
expect(snapshot?.workspaceHistory[0]).toMatchObject({
|
||||
type: "reorder-pages",
|
||||
label: "Move page 2 before page 1",
|
||||
type: 'reorder-pages',
|
||||
label: 'Move page 2 before page 1',
|
||||
});
|
||||
expect(snapshot?.redoHistory).toHaveLength(0);
|
||||
expect(onContentChanged).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("undoes and redoes command records in stack order", () => {
|
||||
it('undoes and redoes command records in stack order', () => {
|
||||
const { ref, onContentChanged } = renderHarness();
|
||||
const initial = state([page("p1", 0), page("p2", 1)], ["p1"], 0);
|
||||
const reordered = state([page("p2", 1), page("p1", 0)], ["p2"], 0);
|
||||
const initial = state([page('p1', 0), page('p2', 1)], ['p1'], 0);
|
||||
const reordered = state([page('p2', 1), page('p1', 0)], ['p2'], 0);
|
||||
|
||||
act(() => {
|
||||
ref.current?.replaceWorkspaceState(initial);
|
||||
@@ -168,13 +168,13 @@ describe("useWorkspaceState", () => {
|
||||
|
||||
act(() => {
|
||||
const command = ref.current?.createWorkspaceCommand({
|
||||
type: "reorder-pages",
|
||||
label: "Move page",
|
||||
type: 'reorder-pages',
|
||||
label: 'Move page',
|
||||
before: initial,
|
||||
after: reordered,
|
||||
});
|
||||
|
||||
if (!command) throw new Error("Command was not created");
|
||||
if (!command) throw new Error('Command was not created');
|
||||
ref.current?.executeWorkspaceCommand(command);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import type { PageRef } from "../pdf/pdfTypes";
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import type { PageRef } from '../pdf/pdfTypes';
|
||||
import type {
|
||||
WorkspaceCommand,
|
||||
WorkspaceCommandRecord,
|
||||
WorkspaceCommandState,
|
||||
} from "./workspaceCommands";
|
||||
} from './workspaceCommands';
|
||||
import {
|
||||
createSnapshotCommand,
|
||||
reviveWorkspaceCommand,
|
||||
toWorkspaceCommandRecord,
|
||||
} from "./workspaceCommands";
|
||||
} from './workspaceCommands';
|
||||
|
||||
function createId(prefix: string): string {
|
||||
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
||||
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ function createId(prefix: string): string {
|
||||
}
|
||||
|
||||
export function createWorkspaceId(): string {
|
||||
return createId("workspace");
|
||||
return createId('workspace');
|
||||
}
|
||||
|
||||
export function createPdfId(): string {
|
||||
@@ -28,11 +28,11 @@ export function createPdfId(): string {
|
||||
}
|
||||
|
||||
export function defaultWorkspaceNameFromPdfName(pdfName: string): string {
|
||||
return pdfName.replace(/\.pdf$/i, "") || "Untitled workspace";
|
||||
return pdfName.replace(/\.pdf$/i, '') || 'Untitled workspace';
|
||||
}
|
||||
|
||||
export function createPageRefId(): string {
|
||||
return createId("page");
|
||||
return createId('page');
|
||||
}
|
||||
|
||||
export function createInitialPageRefs(pageCount: number): PageRef[] {
|
||||
@@ -84,7 +84,7 @@ export function useWorkspaceState({
|
||||
|
||||
const setPages = useCallback((action: SetStateAction<PageRef[]>) => {
|
||||
setPagesState((previous) => {
|
||||
const next = typeof action === "function" ? action(previous) : action;
|
||||
const next = typeof action === 'function' ? action(previous) : action;
|
||||
latestPagesRef.current = next;
|
||||
return next;
|
||||
});
|
||||
@@ -92,7 +92,7 @@ export function useWorkspaceState({
|
||||
|
||||
const setSelectedPageIds = useCallback((action: SetStateAction<string[]>) => {
|
||||
setSelectedPageIdsState((previous) => {
|
||||
const next = typeof action === "function" ? action(previous) : action;
|
||||
const next = typeof action === 'function' ? action(previous) : action;
|
||||
selectedPageIdsRef.current = next;
|
||||
return next;
|
||||
});
|
||||
@@ -101,12 +101,12 @@ export function useWorkspaceState({
|
||||
const setLastSelectedVisualIndex = useCallback(
|
||||
(action: SetStateAction<number | null>) => {
|
||||
setLastSelectedVisualIndexState((previous) => {
|
||||
const next = typeof action === "function" ? action(previous) : action;
|
||||
const next = typeof action === 'function' ? action(previous) : action;
|
||||
lastSelectedVisualIndexRef.current = next;
|
||||
return next;
|
||||
});
|
||||
},
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
const getCurrentCommandState = useCallback(
|
||||
@@ -115,7 +115,7 @@ export function useWorkspaceState({
|
||||
selectedPageIds: selectedPageIdsRef.current,
|
||||
lastSelectedVisualIndex: lastSelectedVisualIndexRef.current,
|
||||
}),
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
const applyCommandState = useCallback(
|
||||
@@ -124,7 +124,7 @@ export function useWorkspaceState({
|
||||
setSelectedPageIds(state.selectedPageIds);
|
||||
setLastSelectedVisualIndex(state.lastSelectedVisualIndex);
|
||||
},
|
||||
[setLastSelectedVisualIndex, setPages, setSelectedPageIds],
|
||||
[setLastSelectedVisualIndex, setPages, setSelectedPageIds]
|
||||
);
|
||||
|
||||
const markWorkspaceChanged = useCallback(() => {
|
||||
@@ -142,14 +142,14 @@ export function useWorkspaceState({
|
||||
details?: Record<string, unknown>;
|
||||
}): WorkspaceCommand =>
|
||||
createSnapshotCommand({
|
||||
id: createId("command"),
|
||||
id: createId('command'),
|
||||
type: params.type,
|
||||
label: params.label,
|
||||
before: params.before,
|
||||
after: params.after,
|
||||
details: params.details,
|
||||
}),
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
const executeWorkspaceCommand = useCallback(
|
||||
@@ -164,7 +164,7 @@ export function useWorkspaceState({
|
||||
setRedoHistory([]);
|
||||
markWorkspaceChanged();
|
||||
},
|
||||
[applyCommandState, getCurrentCommandState, markWorkspaceChanged],
|
||||
[applyCommandState, getCurrentCommandState, markWorkspaceChanged]
|
||||
);
|
||||
|
||||
const handleUndo = useCallback(() => {
|
||||
@@ -213,7 +213,7 @@ export function useWorkspaceState({
|
||||
setWorkspaceDirty(state.dirty ?? false);
|
||||
setWorkspaceMessage(state.message ?? null);
|
||||
},
|
||||
[setLastSelectedVisualIndex, setPages, setSelectedPageIds],
|
||||
[setLastSelectedVisualIndex, setPages, setSelectedPageIds]
|
||||
);
|
||||
|
||||
const resetWorkspaceState = useCallback(() => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { WorkspaceCommandState } from "./workspaceCommands";
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { WorkspaceCommandState } from './workspaceCommands';
|
||||
import {
|
||||
cloneCommandState,
|
||||
createSnapshotCommand,
|
||||
reviveWorkspaceCommand,
|
||||
toWorkspaceCommandRecord,
|
||||
} from "./workspaceCommands";
|
||||
} from './workspaceCommands';
|
||||
|
||||
function makeState(pageIds: string[]): WorkspaceCommandState {
|
||||
return {
|
||||
@@ -19,36 +19,36 @@ function makeState(pageIds: string[]): WorkspaceCommandState {
|
||||
};
|
||||
}
|
||||
|
||||
describe("workspaceCommands", () => {
|
||||
it("clones command state deeply enough for page and selection changes", () => {
|
||||
const original = makeState(["a", "b"]);
|
||||
describe('workspaceCommands', () => {
|
||||
it('clones command state deeply enough for page and selection changes', () => {
|
||||
const original = makeState(['a', 'b']);
|
||||
const cloned = cloneCommandState(original);
|
||||
|
||||
original.pages[0].rotation = 270;
|
||||
original.selectedPageIds.push("b");
|
||||
original.selectedPageIds.push('b');
|
||||
original.lastSelectedVisualIndex = 1;
|
||||
|
||||
expect(cloned).toEqual({
|
||||
pages: [
|
||||
{ id: "a", sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: "b", sourcePageIndex: 1, rotation: 90 },
|
||||
{ id: 'a', sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: 'b', sourcePageIndex: 1, rotation: 90 },
|
||||
],
|
||||
selectedPageIds: ["a"],
|
||||
selectedPageIds: ['a'],
|
||||
lastSelectedVisualIndex: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("creates snapshot commands that are stable after source states mutate", () => {
|
||||
const before = makeState(["a", "b"]);
|
||||
const after = makeState(["b", "a"]);
|
||||
after.selectedPageIds = ["b"];
|
||||
it('creates snapshot commands that are stable after source states mutate', () => {
|
||||
const before = makeState(['a', 'b']);
|
||||
const after = makeState(['b', 'a']);
|
||||
after.selectedPageIds = ['b'];
|
||||
after.lastSelectedVisualIndex = 0;
|
||||
|
||||
const command = createSnapshotCommand({
|
||||
id: "cmd-1",
|
||||
type: "reorder-pages",
|
||||
label: "Move page",
|
||||
timestamp: "2026-05-17T10:00:00.000Z",
|
||||
id: 'cmd-1',
|
||||
type: 'reorder-pages',
|
||||
label: 'Move page',
|
||||
timestamp: '2026-05-17T10:00:00.000Z',
|
||||
before,
|
||||
after,
|
||||
details: { moved: 1 },
|
||||
@@ -56,40 +56,40 @@ describe("workspaceCommands", () => {
|
||||
|
||||
before.pages.length = 0;
|
||||
after.pages[0].rotation = 180;
|
||||
after.selectedPageIds.push("a");
|
||||
after.selectedPageIds.push('a');
|
||||
|
||||
expect(command.undo(makeState(["ignored"]))).toEqual({
|
||||
expect(command.undo(makeState(['ignored']))).toEqual({
|
||||
pages: [
|
||||
{ id: "a", sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: "b", sourcePageIndex: 1, rotation: 90 },
|
||||
{ id: 'a', sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: 'b', sourcePageIndex: 1, rotation: 90 },
|
||||
],
|
||||
selectedPageIds: ["a"],
|
||||
selectedPageIds: ['a'],
|
||||
lastSelectedVisualIndex: 0,
|
||||
});
|
||||
|
||||
expect(command.do(makeState(["ignored"]))).toEqual({
|
||||
expect(command.do(makeState(['ignored']))).toEqual({
|
||||
pages: [
|
||||
{ id: "b", sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: "a", sourcePageIndex: 1, rotation: 90 },
|
||||
{ id: 'b', sourcePageIndex: 0, rotation: 0 },
|
||||
{ id: 'a', sourcePageIndex: 1, rotation: 90 },
|
||||
],
|
||||
selectedPageIds: ["b"],
|
||||
selectedPageIds: ['b'],
|
||||
lastSelectedVisualIndex: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("round-trips commands through serializable records", () => {
|
||||
const before = makeState(["a", "b", "c"]);
|
||||
it('round-trips commands through serializable records', () => {
|
||||
const before = makeState(['a', 'b', 'c']);
|
||||
const after: WorkspaceCommandState = {
|
||||
pages: [before.pages[2], before.pages[0], before.pages[1]],
|
||||
selectedPageIds: ["c"],
|
||||
selectedPageIds: ['c'],
|
||||
lastSelectedVisualIndex: 0,
|
||||
};
|
||||
|
||||
const command = createSnapshotCommand({
|
||||
id: "cmd-2",
|
||||
type: "copy-pages",
|
||||
label: "Copy pages",
|
||||
timestamp: "2026-05-17T10:05:00.000Z",
|
||||
id: 'cmd-2',
|
||||
type: 'copy-pages',
|
||||
label: 'Copy pages',
|
||||
timestamp: '2026-05-17T10:05:00.000Z',
|
||||
before,
|
||||
after,
|
||||
});
|
||||
@@ -97,8 +97,8 @@ describe("workspaceCommands", () => {
|
||||
const record = toWorkspaceCommandRecord(command);
|
||||
const revived = reviveWorkspaceCommand(record);
|
||||
|
||||
expect(record).not.toHaveProperty("do");
|
||||
expect(record).not.toHaveProperty("undo");
|
||||
expect(record).not.toHaveProperty('do');
|
||||
expect(record).not.toHaveProperty('undo');
|
||||
expect(revived.do(before)).toEqual(after);
|
||||
expect(revived.undo(after)).toEqual(before);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PageRef } from "../pdf/pdfTypes";
|
||||
import type { PageRef } from '../pdf/pdfTypes';
|
||||
|
||||
export interface WorkspaceCommandState {
|
||||
pages: PageRef[];
|
||||
@@ -26,7 +26,7 @@ export interface WorkspaceCommand extends WorkspaceCommandRecord {
|
||||
}
|
||||
|
||||
export function cloneCommandState(
|
||||
state: WorkspaceCommandState,
|
||||
state: WorkspaceCommandState
|
||||
): WorkspaceCommandState {
|
||||
return {
|
||||
pages: state.pages.map((page) => ({ ...page })),
|
||||
@@ -58,7 +58,7 @@ export function createSnapshotCommand(params: {
|
||||
}
|
||||
|
||||
export function reviveWorkspaceCommand(
|
||||
record: WorkspaceCommandRecord,
|
||||
record: WorkspaceCommandRecord
|
||||
): WorkspaceCommand {
|
||||
return {
|
||||
...record,
|
||||
@@ -68,7 +68,7 @@ export function reviveWorkspaceCommand(
|
||||
}
|
||||
|
||||
export function toWorkspaceCommandRecord(
|
||||
command: WorkspaceCommand,
|
||||
command: WorkspaceCommand
|
||||
): WorkspaceCommandRecord {
|
||||
return {
|
||||
id: command.id,
|
||||
|
||||
@@ -2,13 +2,13 @@ import type {
|
||||
LoadedWorkspace,
|
||||
StoredWorkspace,
|
||||
WorkspaceSummary,
|
||||
} from "./workspaceTypes";
|
||||
} from './workspaceTypes';
|
||||
|
||||
const DB_NAME = "pdf-tools-workspaces";
|
||||
const DB_NAME = 'pdf-tools-workspaces';
|
||||
const DB_VERSION = 1;
|
||||
|
||||
const WORKSPACE_STORE = "workspaces";
|
||||
const PDF_STORE = "pdfBinaries";
|
||||
const WORKSPACE_STORE = 'workspaces';
|
||||
const PDF_STORE = 'pdfBinaries';
|
||||
|
||||
interface PdfBinaryRecord {
|
||||
pdfId: string;
|
||||
@@ -48,21 +48,21 @@ function openWorkspaceDb(): Promise<IDBDatabase> {
|
||||
|
||||
if (!db.objectStoreNames.contains(WORKSPACE_STORE)) {
|
||||
const workspaceStore = db.createObjectStore(WORKSPACE_STORE, {
|
||||
keyPath: "id",
|
||||
keyPath: 'id',
|
||||
});
|
||||
|
||||
workspaceStore.createIndex("updatedAt", "updatedAt", {
|
||||
workspaceStore.createIndex('updatedAt', 'updatedAt', {
|
||||
unique: false,
|
||||
});
|
||||
|
||||
workspaceStore.createIndex("pdfId", "pdfId", {
|
||||
workspaceStore.createIndex('pdfId', 'pdfId', {
|
||||
unique: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (!db.objectStoreNames.contains(PDF_STORE)) {
|
||||
db.createObjectStore(PDF_STORE, {
|
||||
keyPath: "pdfId",
|
||||
keyPath: 'pdfId',
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -76,7 +76,7 @@ export async function listWorkspaces(): Promise<WorkspaceSummary[]> {
|
||||
const db = await openWorkspaceDb();
|
||||
|
||||
try {
|
||||
const tx = db.transaction(WORKSPACE_STORE, "readonly");
|
||||
const tx = db.transaction(WORKSPACE_STORE, 'readonly');
|
||||
const store = tx.objectStore(WORKSPACE_STORE);
|
||||
|
||||
const records = await requestToPromise<StoredWorkspace[]>(store.getAll());
|
||||
@@ -113,13 +113,13 @@ export async function saveWorkspaceToIndexedDb({
|
||||
const pdfRecord: PdfBinaryRecord = {
|
||||
pdfId: workspace.pdfId,
|
||||
name: workspace.pdfName,
|
||||
blob: new Blob([pdfArrayBuffer], { type: "application/pdf" }),
|
||||
blob: new Blob([pdfArrayBuffer], { type: 'application/pdf' }),
|
||||
size: pdfArrayBuffer.byteLength,
|
||||
createdAt: workspace.createdAt,
|
||||
updatedAt: now,
|
||||
};
|
||||
|
||||
const tx = db.transaction([WORKSPACE_STORE, PDF_STORE], "readwrite");
|
||||
const tx = db.transaction([WORKSPACE_STORE, PDF_STORE], 'readwrite');
|
||||
|
||||
tx.objectStore(PDF_STORE).put(pdfRecord);
|
||||
tx.objectStore(WORKSPACE_STORE).put(workspace);
|
||||
@@ -131,15 +131,15 @@ export async function saveWorkspaceToIndexedDb({
|
||||
}
|
||||
|
||||
export async function loadWorkspaceFromIndexedDb(
|
||||
workspaceId: string,
|
||||
workspaceId: string
|
||||
): Promise<LoadedWorkspace | null> {
|
||||
const db = await openWorkspaceDb();
|
||||
|
||||
try {
|
||||
const tx = db.transaction([WORKSPACE_STORE, PDF_STORE], "readonly");
|
||||
const tx = db.transaction([WORKSPACE_STORE, PDF_STORE], 'readonly');
|
||||
|
||||
const workspace = await requestToPromise<StoredWorkspace | undefined>(
|
||||
tx.objectStore(WORKSPACE_STORE).get(workspaceId),
|
||||
tx.objectStore(WORKSPACE_STORE).get(workspaceId)
|
||||
);
|
||||
|
||||
if (!workspace) {
|
||||
@@ -148,7 +148,7 @@ export async function loadWorkspaceFromIndexedDb(
|
||||
}
|
||||
|
||||
const pdfRecord = await requestToPromise<PdfBinaryRecord | undefined>(
|
||||
tx.objectStore(PDF_STORE).get(workspace.pdfId),
|
||||
tx.objectStore(PDF_STORE).get(workspace.pdfId)
|
||||
);
|
||||
|
||||
await transactionDone(tx);
|
||||
@@ -169,20 +169,20 @@ export async function loadWorkspaceFromIndexedDb(
|
||||
}
|
||||
|
||||
export async function deleteWorkspaceFromIndexedDb(
|
||||
workspaceId: string,
|
||||
workspaceId: string
|
||||
): Promise<void> {
|
||||
const db = await openWorkspaceDb();
|
||||
|
||||
try {
|
||||
const lookupTx = db.transaction(WORKSPACE_STORE, "readonly");
|
||||
const lookupTx = db.transaction(WORKSPACE_STORE, 'readonly');
|
||||
const workspace = await requestToPromise<StoredWorkspace | undefined>(
|
||||
lookupTx.objectStore(WORKSPACE_STORE).get(workspaceId),
|
||||
lookupTx.objectStore(WORKSPACE_STORE).get(workspaceId)
|
||||
);
|
||||
await transactionDone(lookupTx);
|
||||
|
||||
if (!workspace) return;
|
||||
|
||||
const deleteTx = db.transaction([WORKSPACE_STORE, PDF_STORE], "readwrite");
|
||||
const deleteTx = db.transaction([WORKSPACE_STORE, PDF_STORE], 'readwrite');
|
||||
deleteTx.objectStore(WORKSPACE_STORE).delete(workspaceId);
|
||||
await transactionDone(deleteTx);
|
||||
|
||||
@@ -190,14 +190,14 @@ export async function deleteWorkspaceFromIndexedDb(
|
||||
const remainingWorkspaces = await listWorkspaces();
|
||||
|
||||
const pdfStillUsed = remainingWorkspaces.some(
|
||||
(summary) => summary.pdfId === workspace.pdfId,
|
||||
(summary) => summary.pdfId === workspace.pdfId
|
||||
);
|
||||
|
||||
if (!pdfStillUsed) {
|
||||
const cleanupDb = await openWorkspaceDb();
|
||||
|
||||
try {
|
||||
const cleanupTx = cleanupDb.transaction(PDF_STORE, "readwrite");
|
||||
const cleanupTx = cleanupDb.transaction(PDF_STORE, 'readwrite');
|
||||
cleanupTx.objectStore(PDF_STORE).delete(workspace.pdfId);
|
||||
await transactionDone(cleanupTx);
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PageRef } from "../pdf/pdfTypes";
|
||||
import type { WorkspaceCommandRecord } from "./workspaceCommands";
|
||||
import type { PageRef } from '../pdf/pdfTypes';
|
||||
import type { WorkspaceCommandRecord } from './workspaceCommands';
|
||||
|
||||
export interface StoredWorkspace {
|
||||
schemaVersion: 1;
|
||||
|
||||
Reference in New Issue
Block a user