This commit is contained in:
James Brunton 2025-09-02 16:52:50 +00:00 committed by GitHub
commit ea23aaa8d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 955 additions and 44 deletions

View File

@ -24,7 +24,7 @@ indent_size = 2
insert_final_newline = false insert_final_newline = false
trim_trailing_whitespace = false trim_trailing_whitespace = false
[{*.js,*.jsx,*.ts,*.tsx}] [{*.js,*.jsx,*.mjs,*.ts,*.tsx}]
indent_size = 2 indent_size = 2
[*.css] [*.css]

View File

@ -147,6 +147,8 @@ jobs:
cache-dependency-path: frontend/package-lock.json cache-dependency-path: frontend/package-lock.json
- name: Install frontend dependencies - name: Install frontend dependencies
run: cd frontend && npm ci run: cd frontend && npm ci
- name: Lint frontend
run: cd frontend && npm run lint
- name: Build frontend - name: Build frontend
run: cd frontend && npm run build run: cd frontend && npm run build
- name: Run frontend tests - name: Run frontend tests

View File

@ -19,5 +19,6 @@
"yzhang.markdown-all-in-one", // Markdown All-in-One extension for enhanced Markdown editing "yzhang.markdown-all-in-one", // Markdown All-in-One extension for enhanced Markdown editing
"stylelint.vscode-stylelint", // Stylelint extension for CSS and SCSS linting "stylelint.vscode-stylelint", // Stylelint extension for CSS and SCSS linting
"redhat.vscode-yaml", // YAML extension for Visual Studio Code "redhat.vscode-yaml", // YAML extension for Visual Studio Code
"dbaeumer.vscode-eslint", // ESLint extension for TypeScript linting
] ]
} }

View File

@ -0,0 +1,31 @@
// @ts-check
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommended,
{
ignores: [
"dist", // Contains 3rd party code
"public", // Contains 3rd party code
],
},
{
rules: {
"no-empty": "off", // Temporarily disabled until codebase conformant
"no-empty-pattern": "off", // Temporarily disabled until codebase conformant
"no-undef": "off", // Temporarily disabled until codebase conformant
"no-useless-escape": "off", // Temporarily disabled until codebase conformant
"no-case-declarations": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/ban-ts-comment": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/no-empty-object-type": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/no-explicit-any": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/no-require-imports": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/no-unused-expressions": "off", // Temporarily disabled until codebase conformant
"@typescript-eslint/no-unused-vars": "off", // Temporarily disabled until codebase conformant
},
}
);

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,7 @@
"predev": "npm run generate-icons", "predev": "npm run generate-icons",
"dev": "npx tsc --noEmit && vite", "dev": "npx tsc --noEmit && vite",
"prebuild": "npm run generate-icons", "prebuild": "npm run generate-icons",
"lint": "npx eslint",
"build": "npx tsc --noEmit && vite build", "build": "npx tsc --noEmit && vite build",
"preview": "vite preview", "preview": "vite preview",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
@ -72,6 +73,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.34.0",
"@iconify-json/material-symbols": "^1.2.33", "@iconify-json/material-symbols": "^1.2.33",
"@iconify/utils": "^3.0.1", "@iconify/utils": "^3.0.1",
"@playwright/test": "^1.40.0", "@playwright/test": "^1.40.0",
@ -80,6 +82,7 @@
"@types/react-dom": "^19.1.5", "@types/react-dom": "^19.1.5",
"@vitejs/plugin-react": "^4.5.0", "@vitejs/plugin-react": "^4.5.0",
"@vitest/coverage-v8": "^1.0.0", "@vitest/coverage-v8": "^1.0.0",
"eslint": "^9.34.0",
"jsdom": "^23.0.0", "jsdom": "^23.0.0",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"madge": "^8.0.0", "madge": "^8.0.0",
@ -87,7 +90,8 @@
"postcss-cli": "^11.0.1", "postcss-cli": "^11.0.1",
"postcss-preset-mantine": "^1.17.0", "postcss-preset-mantine": "^1.17.0",
"postcss-simple-vars": "^7.0.1", "postcss-simple-vars": "^7.0.1",
"typescript": "^5.8.3", "typescript": "^5.9.2",
"typescript-eslint": "^8.42.0",
"vite": "^6.3.5", "vite": "^6.3.5",
"vitest": "^1.0.0" "vitest": "^1.0.0"
} }

View File

@ -182,7 +182,7 @@ export class EnhancedPDFProcessingService {
): Promise<ProcessedFile> { ): Promise<ProcessedFile> {
const arrayBuffer = await file.arrayBuffer(); const arrayBuffer = await file.arrayBuffer();
const pdf = await pdfWorkerManager.createDocument(arrayBuffer); const pdf = await pdfWorkerManager.createDocument(arrayBuffer);
try { try {
const totalPages = pdf.numPages; const totalPages = pdf.numPages;
@ -519,10 +519,7 @@ export class EnhancedPDFProcessingService {
this.notifyListeners(); this.notifyListeners();
// Force memory cleanup hint // Force memory cleanup hint
if (typeof window !== 'undefined' && window.gc) { setTimeout(() => window.gc?.(), 100);
let gc = window.gc;
setTimeout(() => gc(), 100);
}
} }
/** /**

View File

@ -73,7 +73,7 @@ class IndexedDBManager {
request.onsuccess = () => { request.onsuccess = () => {
const db = request.result; const db = request.result;
console.log(`Successfully opened ${config.name}`); console.log(`Successfully opened ${config.name}`);
// Set up close handler to clean up our references // Set up close handler to clean up our references
db.onclose = () => { db.onclose = () => {
console.log(`Database ${config.name} closed`); console.log(`Database ${config.name} closed`);
@ -87,13 +87,11 @@ class IndexedDBManager {
request.onupgradeneeded = (event) => { request.onupgradeneeded = (event) => {
const db = request.result; const db = request.result;
const oldVersion = event.oldVersion; const oldVersion = event.oldVersion;
console.log(`Upgrading ${config.name} from v${oldVersion} to v${config.version}`); console.log(`Upgrading ${config.name} from v${oldVersion} to v${config.version}`);
// Create or update object stores // Create or update object stores
config.stores.forEach(storeConfig => { config.stores.forEach(storeConfig => {
let store: IDBObjectStore;
if (db.objectStoreNames.contains(storeConfig.name)) { if (db.objectStoreNames.contains(storeConfig.name)) {
// Store exists - for now, just continue (could add migration logic here) // Store exists - for now, just continue (could add migration logic here)
console.log(`Object store '${storeConfig.name}' already exists`); console.log(`Object store '${storeConfig.name}' already exists`);
@ -109,7 +107,7 @@ class IndexedDBManager {
options.autoIncrement = storeConfig.autoIncrement; options.autoIncrement = storeConfig.autoIncrement;
} }
store = db.createObjectStore(storeConfig.name, options); const store = db.createObjectStore(storeConfig.name, options);
console.log(`Created object store '${storeConfig.name}'`); console.log(`Created object store '${storeConfig.name}'`);
// Create indexes // Create indexes
@ -168,7 +166,7 @@ class IndexedDBManager {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const deleteRequest = indexedDB.deleteDatabase(name); const deleteRequest = indexedDB.deleteDatabase(name);
deleteRequest.onerror = () => reject(deleteRequest.error); deleteRequest.onerror = () => reject(deleteRequest.error);
deleteRequest.onsuccess = () => { deleteRequest.onsuccess = () => {
console.log(`Deleted database: ${name}`); console.log(`Deleted database: ${name}`);
@ -224,4 +222,4 @@ export const DATABASE_CONFIGS = {
} as DatabaseConfig } as DatabaseConfig
} as const; } as const;
export const indexedDBManager = IndexedDBManager.getInstance(); export const indexedDBManager = IndexedDBManager.getInstance();

View File

@ -130,7 +130,7 @@ export class PDFExportService {
newDoc.setModificationDate(new Date()); newDoc.setModificationDate(new Date());
const pdfBytes = await newDoc.save(); const pdfBytes = await newDoc.save();
return new Blob([pdfBytes], { type: 'application/pdf' }); return new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });
} }
/** /**
@ -176,7 +176,7 @@ export class PDFExportService {
newDoc.setModificationDate(new Date()); newDoc.setModificationDate(new Date());
const pdfBytes = await newDoc.save(); const pdfBytes = await newDoc.save();
return new Blob([pdfBytes], { type: 'application/pdf' }); return new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });
} }