From 342160b8033a87e4c96673e4576a5babb6837368 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 21 Mar 2026 21:19:24 -0700 Subject: [PATCH] Remove unused frontend npm dependencies (#3935) * Remove unused frontend npm dependencies * Add a guard on database open --- frontend/package-installer.js | 6 +- frontend/package-lock.json | 309 +----------------- frontend/package.json | 9 +- frontend/src/utility-functions/persistence.ts | 155 +++++---- frontend/tsconfig.json | 8 +- 5 files changed, 98 insertions(+), 389 deletions(-) diff --git a/frontend/package-installer.js b/frontend/package-installer.js index a802c712..95f5bb6c 100644 --- a/frontend/package-installer.js +++ b/frontend/package-installer.js @@ -32,11 +32,7 @@ if (isInstallNeeded()) { console.log("Finished installing npm packages."); } catch (_) { // eslint-disable-next-line no-console - console.error( - "\n\n" + - "------------------------------------------------------------> " + - "Failed to install npm packages. Please delete the `node_modules` folder and run `npm install` from the `/frontend` directory.", - ); + console.error("\n\n--------------------> Failed to install npm packages. Please delete `/frontend/node_modules` then try again.\n\n"); process.exit(1); } } else { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7a479aef..c3560c5e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,17 +7,13 @@ "name": "graphite-web-frontend", "license": "Apache-2.0", "dependencies": { - "idb-keyval": "^6.2.2", "source-code-pro": "2.42.0", "source-sans-pro": "2.45.0" }, "devDependencies": { - "@eslint/compat": "^2.0.3", - "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.39.2", "@sveltejs/vite-plugin-svelte": "^7.0.0", "@types/node": "^25.5.0", - "buffer": "^6.0.3", "concurrently": "^9.2.1", "eslint": "^9.39.2", "eslint-import-resolver-typescript": "^4.4.4", @@ -26,46 +22,19 @@ "eslint-plugin-svelte": "^3.16.0", "globals": "^17.4.0", "license-checker-rseidelsohn": "^4.4.2", - "postcss": "^8.5.8", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.5.1", - "process": "^0.11.10", "sass": "^1.98.0", "svelte": "^5.54.1", "svelte-check": "^4.4.5", "svelte-preprocess": "^6.0.3", "tar": "^7.5.12", - "ts-node": "^10.9.2", "typescript": "^5.9.3", "typescript-eslint": "^8.57.1", "vite": "^8.0.1", "vite-multiple-assets": "2.2.6" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@emnapi/core": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", @@ -142,27 +111,6 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/compat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.0.3.tgz", - "integrity": "sha512-SjIJhGigp8hmd1YGIBwh7Ovri7Kisl42GYFjrOyHhtfYGGoLW6teYi/5p8W50KSsawUPpuLOSmsq1bD0NGQLBw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "peerDependencies": { - "eslint": "^8.40 || 9 || 10" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, "node_modules/@eslint/config-array": { "version": "0.21.2", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", @@ -191,7 +139,7 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { + "node_modules/@eslint/core": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", @@ -204,19 +152,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", - "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, "node_modules/@eslint/eslintrc": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", @@ -291,19 +226,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1524,34 +1446,6 @@ "vite": "^8.0.0-beta.7 || ^8.0.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -2198,19 +2092,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", - "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", @@ -2257,13 +2138,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2456,27 +2330,6 @@ "dev": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2501,31 +2354,6 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2782,13 +2610,6 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2959,16 +2780,6 @@ "dev": true, "license": "MIT" }, - "node_modules/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3518,19 +3329,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/esm-env": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", @@ -4167,33 +3965,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/idb-keyval": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz", - "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", - "license": "Apache-2.0" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -5174,13 +4945,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -5898,16 +5662,6 @@ "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7069,50 +6823,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -7340,13 +7050,6 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -7791,16 +7494,6 @@ "node": ">=8" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 62c30317..7e9f7ee6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,17 +28,13 @@ }, "//": "NOTE: `source-sans-pro` is never to be upgraded to 3.x because that renders 1px above its intended position.", "dependencies": { - "idb-keyval": "^6.2.2", "source-code-pro": "2.42.0", "source-sans-pro": "2.45.0" }, "devDependencies": { - "@eslint/compat": "^2.0.3", - "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.39.2", "@sveltejs/vite-plugin-svelte": "^7.0.0", "@types/node": "^25.5.0", - "buffer": "^6.0.3", "concurrently": "^9.2.1", "eslint": "^9.39.2", "eslint-import-resolver-typescript": "^4.4.4", @@ -46,17 +42,14 @@ "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-svelte": "^3.16.0", "globals": "^17.4.0", - "svelte-check": "^4.4.5", "license-checker-rseidelsohn": "^4.4.2", - "postcss": "^8.5.8", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.5.1", - "process": "^0.11.10", "sass": "^1.98.0", "svelte": "^5.54.1", + "svelte-check": "^4.4.5", "svelte-preprocess": "^6.0.3", "tar": "^7.5.12", - "ts-node": "^10.9.2", "typescript": "^5.9.3", "typescript-eslint": "^8.57.1", "vite": "^8.0.1", diff --git a/frontend/src/utility-functions/persistence.ts b/frontend/src/utility-functions/persistence.ts index 144bc713..15156afb 100644 --- a/frontend/src/utility-functions/persistence.ts +++ b/frontend/src/utility-functions/persistence.ts @@ -1,73 +1,55 @@ -import * as idb from "idb-keyval"; import { get } from "svelte/store"; import type { PortfolioStore } from "/src/stores/portfolio"; import type { MessageBody } from "/src/subscriptions-router"; import type { EditorWrapper } from "/wrapper/pkg/graphite_wasm_wrapper"; -export async function storeCurrentDocumentId(documentId: string) { - const indexedDbStorage = idb.createStore("graphite", "store"); +const PERSISTENCE_DB = "graphite"; +const PERSISTENCE_STORE = "store"; - await idb.set("current_document_id", String(documentId), indexedDbStorage); +export async function storeCurrentDocumentId(documentId: string) { + await databaseSet("current_document_id", String(documentId)); } export async function storeDocument(autoSaveDocument: MessageBody<"TriggerPersistenceWriteDocument">, portfolio: PortfolioStore) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - await idb.update>>( - "documents", - (old) => { - const documents = old || {}; - documents[String(autoSaveDocument.documentId)] = autoSaveDocument; - return documents; - }, - indexedDbStorage, - ); + await databaseUpdate>>("documents", (old) => { + const documents = old || {}; + documents[String(autoSaveDocument.documentId)] = autoSaveDocument; + return documents; + }); const documentOrder = get(portfolio).documents.map((doc) => String(doc.id)); - await idb.set("documents_tab_order", documentOrder, indexedDbStorage); + await databaseSet("documents_tab_order", documentOrder); await storeCurrentDocumentId(String(autoSaveDocument.documentId)); } export async function removeDocument(id: string, portfolio: PortfolioStore) { - const indexedDbStorage = idb.createStore("graphite", "store"); + await databaseUpdate>>("documents", (old) => { + const documents = old || {}; + delete documents[id]; + return documents; + }); - await idb.update>>( - "documents", - (old) => { - const documents = old || {}; - delete documents[id]; - return documents; - }, - indexedDbStorage, - ); - - await idb.update( - "documents_tab_order", - (old) => { - const order = old || []; - return order.filter((docId) => docId !== id); - }, - indexedDbStorage, - ); + await databaseUpdate("documents_tab_order", (old) => { + const order = old || []; + return order.filter((docId) => docId !== id); + }); const documentCount = get(portfolio).documents.length; if (documentCount > 0) { const documentIndex = get(portfolio).activeDocumentIndex; const documentId = String(get(portfolio).documents[documentIndex].id); - const tabOrder = (await idb.get("documents_tab_order", indexedDbStorage)) || []; + const tabOrder = (await databaseGet("documents_tab_order")) || []; if (tabOrder.includes(documentId)) { await storeCurrentDocumentId(documentId); } } else { - await idb.del("current_document_id", indexedDbStorage); + await databaseDelete("current_document_id"); } } export async function loadFirstDocument(editor: EditorWrapper) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - const previouslySavedDocuments = await idb.get>>("documents", indexedDbStorage); + const previouslySavedDocuments = await databaseGet>>("documents"); // TODO: Eventually remove this document upgrade code // Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if the browser is storing the old format as strings @@ -77,8 +59,8 @@ export async function loadFirstDocument(editor: EditorWrapper) { }); } - const documentOrder = await idb.get("documents_tab_order", indexedDbStorage); - const currentDocumentIdString = await idb.get("current_document_id", indexedDbStorage); + const documentOrder = await databaseGet("documents_tab_order"); + const currentDocumentIdString = await databaseGet("current_document_id"); const currentDocumentId = currentDocumentIdString ? BigInt(currentDocumentIdString) : undefined; if (!previouslySavedDocuments || !documentOrder) return; @@ -99,9 +81,7 @@ export async function loadFirstDocument(editor: EditorWrapper) { } export async function loadRestDocuments(editor: EditorWrapper) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - const previouslySavedDocuments = await idb.get>>("documents", indexedDbStorage); + const previouslySavedDocuments = await databaseGet>>("documents"); // TODO: Eventually remove this document upgrade code // Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if needed @@ -111,8 +91,8 @@ export async function loadRestDocuments(editor: EditorWrapper) { }); } - const documentOrder = await idb.get("documents_tab_order", indexedDbStorage); - const currentDocumentIdString = await idb.get("current_document_id", indexedDbStorage); + const documentOrder = await databaseGet("documents_tab_order"); + const currentDocumentIdString = await databaseGet("current_document_id"); const currentDocumentId = currentDocumentIdString ? BigInt(currentDocumentIdString) : undefined; if (!previouslySavedDocuments || !documentOrder) return; @@ -150,9 +130,7 @@ export async function loadRestDocuments(editor: EditorWrapper) { } export async function saveActiveDocument(documentId: bigint) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - const previouslySavedDocuments = await idb.get>>("documents", indexedDbStorage); + const previouslySavedDocuments = await databaseGet>>("documents"); const documentIdString = String(documentId); @@ -171,22 +149,77 @@ export async function saveActiveDocument(documentId: bigint) { } export async function saveEditorPreferences(preferences: unknown) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - await idb.set("preferences", preferences, indexedDbStorage); + await databaseSet("preferences", preferences); } export async function loadEditorPreferences(editor: EditorWrapper) { - const indexedDbStorage = idb.createStore("graphite", "store"); - - const preferences = await idb.get>("preferences", indexedDbStorage); + const preferences = await databaseGet>("preferences"); editor.loadPreferences(preferences ? JSON.stringify(preferences) : undefined); } export async function wipeDocuments() { - const indexedDbStorage = idb.createStore("graphite", "store"); - - await idb.del("documents_tab_order", indexedDbStorage); - await idb.del("current_document_id", indexedDbStorage); - await idb.del("documents", indexedDbStorage); + await databaseDelete("documents_tab_order"); + await databaseDelete("current_document_id"); + await databaseDelete("documents"); +} + +function databaseOpen(): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.open(PERSISTENCE_DB, 1); + request.onupgradeneeded = () => { + if (!request.result.objectStoreNames.contains(PERSISTENCE_STORE)) { + request.result.createObjectStore(PERSISTENCE_STORE); + } + }; + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); +} + +async function databaseGet(key: string): Promise { + const db = await databaseOpen(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(PERSISTENCE_STORE, "readonly"); + const request = transaction.objectStore(PERSISTENCE_STORE).get(key); + request.onsuccess = () => { + const result: T | undefined = request.result; + resolve(result); + }; + request.onerror = () => reject(request.error); + }); +} + +async function databaseSet(key: string, value: unknown): Promise { + const db = await databaseOpen(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(PERSISTENCE_STORE, "readwrite"); + transaction.objectStore(PERSISTENCE_STORE).put(value, key); + transaction.oncomplete = () => resolve(); + transaction.onerror = () => reject(transaction.error); + }); +} + +async function databaseDelete(key: string): Promise { + const db = await databaseOpen(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(PERSISTENCE_STORE, "readwrite"); + transaction.objectStore(PERSISTENCE_STORE).delete(key); + transaction.oncomplete = () => resolve(); + transaction.onerror = () => reject(transaction.error); + }); +} + +async function databaseUpdate(key: string, updater: (existing: T | undefined) => T): Promise { + const db = await databaseOpen(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(PERSISTENCE_STORE, "readwrite"); + const store = transaction.objectStore(PERSISTENCE_STORE); + const getRequest = store.get(key); + getRequest.onsuccess = () => { + const existing: T | undefined = getRequest.result; + store.put(updater(existing), key); + }; + transaction.oncomplete = () => resolve(); + transaction.onerror = () => reject(transaction.error); + }); } diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 34dceb82..bda46057 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -12,11 +12,5 @@ "paths": { "/*": ["./*"] }, "lib": ["ESNext", "DOM", "DOM.Iterable"] }, - "include": ["src/**/*.ts", "src/**/*.svelte", "*.ts"], - "ts-node": { - "compilerOptions": { - "useDefineForClassFields": false, - "noImplicitOverride": true - } - } + "include": ["src/**/*.ts", "src/**/*.svelte", "*.ts"] }