Remove unused frontend npm dependencies (#3935)

* Remove unused frontend npm dependencies

* Add a guard on database open
This commit is contained in:
Keavon Chambers 2026-03-21 21:19:24 -07:00 committed by GitHub
parent 06f27f1d3a
commit 342160b803
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 98 additions and 389 deletions

View File

@ -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 {

View File

@ -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",

View File

@ -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",

View File

@ -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<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>(
"documents",
(old) => {
const documents = old || {};
documents[String(autoSaveDocument.documentId)] = autoSaveDocument;
return documents;
},
indexedDbStorage,
);
await databaseUpdate<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("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<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", (old) => {
const documents = old || {};
delete documents[id];
return documents;
});
await idb.update<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>(
"documents",
(old) => {
const documents = old || {};
delete documents[id];
return documents;
},
indexedDbStorage,
);
await idb.update<string[]>(
"documents_tab_order",
(old) => {
const order = old || [];
return order.filter((docId) => docId !== id);
},
indexedDbStorage,
);
await databaseUpdate<string[]>("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<string[]>("documents_tab_order", indexedDbStorage)) || [];
const tabOrder = (await databaseGet<string[]>("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<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", indexedDbStorage);
const previouslySavedDocuments = await databaseGet<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("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<string[]>("documents_tab_order", indexedDbStorage);
const currentDocumentIdString = await idb.get<string>("current_document_id", indexedDbStorage);
const documentOrder = await databaseGet<string[]>("documents_tab_order");
const currentDocumentIdString = await databaseGet<string>("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<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", indexedDbStorage);
const previouslySavedDocuments = await databaseGet<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("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<string[]>("documents_tab_order", indexedDbStorage);
const currentDocumentIdString = await idb.get<string>("current_document_id", indexedDbStorage);
const documentOrder = await databaseGet<string[]>("documents_tab_order");
const currentDocumentIdString = await databaseGet<string>("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<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", indexedDbStorage);
const previouslySavedDocuments = await databaseGet<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("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<Record<string, unknown>>("preferences", indexedDbStorage);
const preferences = await databaseGet<Record<string, unknown>>("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<IDBDatabase> {
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<T>(key: string): Promise<T | undefined> {
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<void> {
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<void> {
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<T>(key: string, updater: (existing: T | undefined) => T): Promise<void> {
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);
});
}

View File

@ -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"]
}