mirror of
https://github.com/philips/supernote-obsidian-plugin.git
synced 2026-07-22 09:50:25 +00:00
main: parallelize image processing
This reduces the procsesing time of the 1to10.note from about 7 seconds to 1.5s. It should be significant for anyone with note files with many pages.
This commit is contained in:
parent
439506b58e
commit
9f3ed397d4
7 changed files with 346 additions and 55 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import esbuild from "esbuild";
|
||||
import process from "process";
|
||||
import builtins from "builtin-modules";
|
||||
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
|
||||
|
||||
const banner =
|
||||
`/*
|
||||
|
|
@ -15,8 +16,12 @@ const context = await esbuild.context({
|
|||
banner: {
|
||||
js: banner,
|
||||
},
|
||||
entryPoints: ["main.ts"],
|
||||
entryPoints: ["src/main.ts"],
|
||||
alias: {
|
||||
'supernote-typescript': 'supernote-typescript'
|
||||
},
|
||||
bundle: true,
|
||||
plugins: [inlineWorkerPlugin()],
|
||||
external: [
|
||||
"obsidian",
|
||||
"electron",
|
||||
|
|
|
|||
190
package-lock.json
generated
190
package-lock.json
generated
|
|
@ -9,6 +9,7 @@
|
|||
"version": "2.3.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild-plugin-inline-worker": "^0.1.1",
|
||||
"image-js": "^0.35.5",
|
||||
"supernote": "github:philips/supernote-typescript"
|
||||
},
|
||||
|
|
@ -189,7 +190,6 @@
|
|||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
|
|
@ -205,7 +205,6 @@
|
|||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
|
|
@ -221,7 +220,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
|
|
@ -237,7 +235,6 @@
|
|||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
|
|
@ -253,7 +250,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
|
|
@ -269,7 +265,6 @@
|
|||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
|
|
@ -285,7 +280,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
|
|
@ -301,7 +295,6 @@
|
|||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -317,7 +310,6 @@
|
|||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -333,7 +325,6 @@
|
|||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -349,7 +340,6 @@
|
|||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -365,7 +355,6 @@
|
|||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -381,7 +370,6 @@
|
|||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -397,7 +385,6 @@
|
|||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -413,7 +400,6 @@
|
|||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -429,7 +415,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
|
|
@ -445,7 +430,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
|
|
@ -461,7 +445,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
|
|
@ -477,7 +460,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
|
|
@ -493,7 +475,6 @@
|
|||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
|
|
@ -509,7 +490,6 @@
|
|||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
|
|
@ -525,7 +505,6 @@
|
|||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
|
|
@ -1567,12 +1546,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -1673,6 +1653,12 @@
|
|||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
|
@ -1681,10 +1667,11 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
|
|
@ -1765,7 +1752,6 @@
|
|||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz",
|
||||
"integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
|
|
@ -1798,6 +1784,16 @@
|
|||
"@esbuild/win32-x64": "0.17.3"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-plugin-inline-worker": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-plugin-inline-worker/-/esbuild-plugin-inline-worker-0.1.1.tgz",
|
||||
"integrity": "sha512-VmFqsQKxUlbM51C1y5bRiMeyc1x2yTdMXhKB6S//++g9aCBg8TfGsbKxl5ZDkCGquqLY+RmEk93TBNd0i35dPA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "latest",
|
||||
"find-cache-dir": "^3.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
|
|
@ -2173,10 +2169,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
|
|
@ -2184,6 +2181,23 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/find-cache-dir": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
|
||||
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commondir": "^1.0.1",
|
||||
"make-dir": "^3.0.2",
|
||||
"pkg-dir": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/find-up": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||
|
|
@ -2510,6 +2524,7 @@
|
|||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
|
|
@ -2731,6 +2746,30 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/median-quickselect": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/median-quickselect/-/median-quickselect-1.0.1.tgz",
|
||||
|
|
@ -2746,12 +2785,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -3080,6 +3120,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||
|
|
@ -3102,8 +3151,6 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -3155,6 +3202,70 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"find-up": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir/node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir/node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir/node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir/node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
|
|
@ -3531,6 +3642,7 @@
|
|||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
"typescript": "4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"esbuild-plugin-inline-worker": "^0.1.1",
|
||||
"image-js": "^0.35.5",
|
||||
"supernote": "github:philips/supernote-typescript"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { App, Modal, TFolder, TFile, Plugin, PluginSettingTab, Editor, Setting, MarkdownView, WorkspaceLeaf, FileView } from 'obsidian';
|
||||
import { SupernoteX, toImage, fetchMirrorFrame } from 'supernote-typescript';
|
||||
import { App, Modal, TFile, Plugin, PluginSettingTab, Editor, Setting, MarkdownView, WorkspaceLeaf, FileView } from 'obsidian';
|
||||
import { SupernoteX, fetchMirrorFrame } from 'supernote-typescript';
|
||||
import { Image } from 'image-js'
|
||||
import { SupernoteWorkerMessage, SupernoteWorkerResponse } from './myworker.worker';
|
||||
import Worker from 'myworker.worker';
|
||||
|
||||
interface SupernotePluginSettings {
|
||||
mirrorIP: string;
|
||||
|
|
@ -32,6 +35,107 @@ function generateTimestamp(): string {
|
|||
return timestamp;
|
||||
}
|
||||
|
||||
function dataUrlToBuffer(dataUrl: string): ArrayBuffer {
|
||||
// Remove data URL prefix (e.g., "data:image/png;base64,")
|
||||
const base64 = dataUrl.split(',')[1];
|
||||
// Convert base64 to binary string
|
||||
const binaryString = atob(base64);
|
||||
// Create buffer and view
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
// Convert binary string to buffer
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
|
||||
export class WorkerPool {
|
||||
private workers: Worker[];
|
||||
|
||||
constructor(private maxWorkers: number = navigator.hardwareConcurrency) {
|
||||
this.workers = Array(maxWorkers).fill(null).map(() =>
|
||||
new Worker()
|
||||
);
|
||||
}
|
||||
|
||||
private processChunk(worker: Worker, note: SupernoteX, pageNumbers: number[]): Promise<any[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
worker.onmessage = (e: MessageEvent<SupernoteWorkerResponse>) => {
|
||||
const duration = Date.now() - startTime;
|
||||
//console.log(`Processed pages ${pageNumbers.join(',')} in ${duration}ms`);
|
||||
|
||||
if (e.data.error) {
|
||||
reject(new Error(e.data.error));
|
||||
} else {
|
||||
resolve(e.data.images);
|
||||
}
|
||||
};
|
||||
|
||||
worker.onerror = (error) => {
|
||||
console.error('Worker error:', error);
|
||||
reject(error);
|
||||
};
|
||||
|
||||
const message: SupernoteWorkerMessage = {
|
||||
type: 'convert',
|
||||
note,
|
||||
pageNumbers
|
||||
};
|
||||
|
||||
worker.postMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
async processPages(note: SupernoteX, allPageNumbers: number[]): Promise<any[]> {
|
||||
//console.time('Total processing time');
|
||||
|
||||
// Split pages into chunks based on number of workers
|
||||
const chunkSize = Math.ceil(allPageNumbers.length / this.workers.length);
|
||||
const chunks: number[][] = [];
|
||||
|
||||
for (let i = 0; i < allPageNumbers.length; i += chunkSize) {
|
||||
chunks.push(allPageNumbers.slice(i, i + chunkSize));
|
||||
}
|
||||
|
||||
//console.log(`Processing ${allPageNumbers.length} pages in ${chunks.length} chunks`);
|
||||
|
||||
// Process chunks in parallel using available workers
|
||||
const results = await Promise.all(
|
||||
chunks.map((chunk, index) =>
|
||||
this.processChunk(this.workers[index % this.workers.length], note, chunk)
|
||||
)
|
||||
);
|
||||
|
||||
//console.timeEnd('Total processing time');
|
||||
return results.flat();
|
||||
}
|
||||
|
||||
terminate() {
|
||||
this.workers.forEach(worker => worker.terminate());
|
||||
this.workers = [];
|
||||
}
|
||||
}
|
||||
|
||||
export class ImageConverter {
|
||||
private workerPool: WorkerPool;
|
||||
|
||||
constructor(maxWorkers = navigator.hardwareConcurrency) { // Default to 4 workers
|
||||
this.workerPool = new WorkerPool(maxWorkers);
|
||||
}
|
||||
|
||||
async convertToImages(note: SupernoteX, pageNumbers?: number[]): Promise<any[]> {
|
||||
const pages = pageNumbers ?? Array.from({length: note.pages.length}, (_, i) => i+1);
|
||||
const results = await this.workerPool.processPages(note, pages);
|
||||
return results;
|
||||
}
|
||||
|
||||
terminate() {
|
||||
this.workerPool.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
class VaultWriter {
|
||||
app: App;
|
||||
settings: SupernotePluginSettings;
|
||||
|
|
@ -74,11 +178,21 @@ class VaultWriter {
|
|||
}
|
||||
|
||||
async writeImageFiles(file: TFile, sn: SupernoteX): Promise<TFile[]> {
|
||||
let images = await toImage(sn);
|
||||
let images: string[] = [];
|
||||
|
||||
const converter = new ImageConverter();
|
||||
try {
|
||||
images = await converter.convertToImages(sn);
|
||||
} finally {
|
||||
// Clean up the worker when done
|
||||
converter.terminate();
|
||||
}
|
||||
|
||||
let imgs: TFile[] = [];
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
let filename = await this.app.fileManager.getAvailablePathForAttachment(`${file.basename}-${i}.png`);
|
||||
imgs.push(await this.app.vault.createBinary(filename, images[i].toBuffer()));
|
||||
const buffer = dataUrlToBuffer(images[i]);
|
||||
imgs.push(await this.app.vault.createBinary(filename, buffer));
|
||||
}
|
||||
return imgs;
|
||||
}
|
||||
|
|
@ -128,7 +242,15 @@ export class SupernoteView extends FileView {
|
|||
|
||||
const note = await this.app.vault.readBinary(file);
|
||||
let sn = new SupernoteX(new Uint8Array(note));
|
||||
let images = await toImage(sn);
|
||||
let images: string[] = [];
|
||||
|
||||
const converter = new ImageConverter();
|
||||
try {
|
||||
images = await converter.convertToImages(sn);
|
||||
} finally {
|
||||
// Clean up the worker when done
|
||||
converter.terminate();
|
||||
}
|
||||
|
||||
if (this.settings.showExportButtons) {
|
||||
const exportNoteBtn = container.createEl("p").createEl("button", {
|
||||
|
|
@ -163,7 +285,7 @@ export class SupernoteView extends FileView {
|
|||
}
|
||||
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
const imageDataUrl = images[i].toDataURL();
|
||||
const imageDataUrl = images[i];
|
||||
|
||||
const pageContainer = container.createEl("div", {
|
||||
cls: 'page-container',
|
||||
|
|
@ -214,7 +336,8 @@ export class SupernoteView extends FileView {
|
|||
|
||||
saveButton.addEventListener("click", async () => {
|
||||
const filename = await this.app.fileManager.getAvailablePathForAttachment(`${file.basename}}.png`);
|
||||
await this.app.vault.createBinary(filename, images[i].toBuffer());
|
||||
const buffer = dataUrlToBuffer(imageDataUrl);
|
||||
await this.app.vault.createBinary(filename, buffer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -472,7 +595,7 @@ class SupernoteSettingTab extends PluginSettingTab {
|
|||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Max image side length in .note files')
|
||||
.setDesc('Maximum width and height (in pixels) of the note image when viewing .note files. Does not affect exported images and markdown.')
|
||||
45
src/myworker.worker.ts
Normal file
45
src/myworker.worker.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { SupernoteX, toImage } from 'supernote-typescript';
|
||||
import { Image } from 'image-js'
|
||||
|
||||
export {};
|
||||
|
||||
export type SupernoteWorkerMessage = {
|
||||
type: 'convert';
|
||||
note: SupernoteX;
|
||||
pageNumbers?: number[];
|
||||
}
|
||||
|
||||
export type SupernoteWorkerResponse = {
|
||||
type: 'result';
|
||||
images: string[];
|
||||
error?: string;
|
||||
}
|
||||
|
||||
self.onmessage = async (e: MessageEvent<SupernoteWorkerMessage>) => {
|
||||
try {
|
||||
const { type, note, pageNumbers } = e.data;
|
||||
|
||||
if (type === 'convert') {
|
||||
const results = await toImage(note, pageNumbers);
|
||||
// Convert canvas/images to data URLs before sending
|
||||
const dataUrls = results.map(result => {
|
||||
if (result && typeof result.toDataURL === 'function') {
|
||||
return result.toDataURL();
|
||||
}
|
||||
console.error('Result is not a canvas or does not support toDataURL');
|
||||
return null;
|
||||
});
|
||||
|
||||
self.postMessage({
|
||||
type: 'result',
|
||||
images: dataUrls
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
self.postMessage({
|
||||
type: 'result',
|
||||
images: [],
|
||||
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
||||
});
|
||||
}
|
||||
};
|
||||
4
src/worker.d.ts
vendored
Normal file
4
src/worker.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
declare module 'myworker.worker' {
|
||||
const WorkerFactory: new () => Worker;
|
||||
export default WorkerFactory;
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"baseUrl": "./src/",
|
||||
"paths": {
|
||||
"supernote-typescript": ["../supernote-typescript/src/"]
|
||||
},
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
|
|
@ -11,18 +14,16 @@
|
|||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"strictNullChecks": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7"
|
||||
"ES7",
|
||||
"DOM.Iterable"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"supernote-typescript/**/*.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
"supernote-typescript/tests/*.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue