refactor background to use ttl cache

This commit is contained in:
0xtsukino
2023-08-24 17:44:33 -07:00
committed by tsukino
parent 0af84cf1d6
commit f4f80c8b85
32 changed files with 590 additions and 264 deletions

33
.eslintrc Normal file
View File

@@ -0,0 +1,33 @@
{
root: true,
"extends": ["prettier", "plugin:@typescript-eslint/recommended"],
"plugins": ["prettier", "@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"rules": {
"prettier/prettier": "error",
"@typescript-eslint/no-explicit-any": 1,
"@typescript-eslint/no-var-requires": 0,
"no-undef": "error",
"padding-line-between-statements": "error"
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest"
},
"env": {
"webextensions": true,
"es6": true,
"browser": true,
"node": true
},
"settings": {
"import/resolver": "typescript"
},
"ignorePatterns": [
"build",
"wasm",
"tlsn",
"util",
"webpack.config.js"
]
}

View File

@@ -1,5 +1,6 @@
build
node_modules
wasm
tlsn
postcss.config.js
webpack.config.js

9
.prettierrc.json Normal file
View File

@@ -0,0 +1,9 @@
{
"printWidth": 80,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always"
}

View File

@@ -11,16 +11,20 @@
"build:wasm": "wasm-pack build --target web wasm/prover",
"build": "node utils/build.js",
"dev": "node utils/webserver.js",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prettier": "prettier --write '**/*.{js,jsx,ts,tsx,json,css,scss,md}'"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.2",
"@isaacs/ttlcache": "^1.4.1",
"async-mutex": "^0.4.0",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"comlink": "^4.4.1",
"fast-deep-equal": "^3.1.3",
"fuse.js": "^6.6.2",
"node-cache": "^5.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.2",
@@ -50,10 +54,12 @@
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"eslint": "^8.31.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-import": "^2.27.4",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.32.0",
"eslint-plugin-react-hooks": "^4.6.0",
"file-loader": "^6.2.0",
@@ -62,7 +68,7 @@
"html-webpack-plugin": "^5.5.0",
"postcss-loader": "^7.3.3",
"postcss-preset-env": "^9.1.1",
"prettier": "^2.8.3",
"prettier": "^3.0.2",
"react-refresh": "^0.14.0",
"react-refresh-typescript": "^2.0.7",
"sass": "^1.57.1",

247
pnpm-lock.yaml generated
View File

@@ -14,6 +14,9 @@ dependencies:
async-mutex:
specifier: ^0.4.0
version: 0.4.0
buffer:
specifier: ^6.0.3
version: 6.0.3
classnames:
specifier: ^2.3.2
version: 2.3.2
@@ -26,6 +29,9 @@ dependencies:
fuse.js:
specifier: ^6.6.2
version: 6.6.2
node-cache:
specifier: ^5.1.2
version: 5.1.2
react:
specifier: ^18.2.0
version: 18.2.0
@@ -109,6 +115,9 @@ devDependencies:
eslint:
specifier: ^8.31.0
version: 8.46.0
eslint-config-prettier:
specifier: ^9.0.0
version: 9.0.0(eslint@8.46.0)
eslint-config-react-app:
specifier: ^7.0.1
version: 7.0.1(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.46.0)(typescript@4.9.5)
@@ -121,6 +130,9 @@ devDependencies:
eslint-plugin-jsx-a11y:
specifier: ^6.7.1
version: 6.7.1(eslint@8.46.0)
eslint-plugin-prettier:
specifier: ^5.0.0
version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.46.0)(prettier@3.0.2)
eslint-plugin-react:
specifier: ^7.32.0
version: 7.33.1(eslint@8.46.0)
@@ -146,8 +158,8 @@ devDependencies:
specifier: ^9.1.1
version: 9.1.1(postcss@8.4.27)
prettier:
specifier: ^2.8.3
version: 2.8.8
specifier: ^3.0.2
version: 3.0.2
react-refresh:
specifier: ^0.14.0
version: 0.14.0
@@ -2096,6 +2108,18 @@ packages:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
/@pkgr/utils@2.4.2:
resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
dependencies:
cross-spawn: 7.0.3
fast-glob: 3.3.1
is-glob: 4.0.3
open: 9.1.0
picocolors: 1.0.0
tslib: 2.6.1
dev: true
/@pmmmwh/react-refresh-webpack-plugin@0.5.10(react-refresh@0.14.0)(type-fest@3.13.1)(webpack-dev-server@4.15.1)(webpack@5.88.2):
resolution: {integrity: sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==}
engines: {node: '>= 10.13'}
@@ -3045,10 +3069,19 @@ packages:
/balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: false
/batch@0.6.1:
resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==}
dev: true
/big-integer@1.6.51:
resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
engines: {node: '>=0.6'}
dev: true
/big.js@5.2.2:
resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
dev: true
@@ -3090,6 +3123,13 @@ packages:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
dev: true
/bplist-parser@0.2.0:
resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==}
engines: {node: '>= 5.10.0'}
dependencies:
big-integer: 1.6.51
dev: true
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@@ -3121,6 +3161,20 @@ packages:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
dev: false
/bundle-name@3.0.0:
resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==}
engines: {node: '>=12'}
dependencies:
run-applescript: 5.0.0
dev: true
/bytes@3.0.0:
resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
engines: {node: '>= 0.8'}
@@ -3225,6 +3279,11 @@ packages:
shallow-clone: 3.0.1
dev: true
/clone@2.1.2:
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
engines: {node: '>=0.8'}
dev: false
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -3522,6 +3581,24 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/default-browser-id@3.0.0:
resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==}
engines: {node: '>=12'}
dependencies:
bplist-parser: 0.2.0
untildify: 4.0.0
dev: true
/default-browser@4.0.0:
resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==}
engines: {node: '>=14.16'}
dependencies:
bundle-name: 3.0.0
default-browser-id: 3.0.0
execa: 7.2.0
titleize: 3.0.0
dev: true
/default-gateway@6.0.3:
resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==}
engines: {node: '>= 10'}
@@ -3534,6 +3611,11 @@ packages:
engines: {node: '>=8'}
dev: true
/define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
dev: true
/define-properties@1.2.0:
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
engines: {node: '>= 0.4'}
@@ -3808,6 +3890,15 @@ packages:
engines: {node: '>=10'}
dev: true
/eslint-config-prettier@9.0.0(eslint@8.46.0):
resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.46.0
dev: true
/eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.46.0)(typescript@4.9.5):
resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==}
engines: {node: '>=14.0.0'}
@@ -3979,6 +4070,27 @@ packages:
semver: 6.3.1
dev: true
/eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.46.0)(prettier@3.0.2):
resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
'@types/eslint': '>=8.0.0'
eslint: '>=8.0.0'
eslint-config-prettier: '*'
prettier: '>=3.0.0'
peerDependenciesMeta:
'@types/eslint':
optional: true
eslint-config-prettier:
optional: true
dependencies:
eslint: 8.46.0
eslint-config-prettier: 9.0.0(eslint@8.46.0)
prettier: 3.0.2
prettier-linter-helpers: 1.0.0
synckit: 0.8.5
dev: true
/eslint-plugin-react-hooks@4.6.0(eslint@8.46.0):
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
engines: {node: '>=10'}
@@ -4169,6 +4281,21 @@ packages:
strip-final-newline: 2.0.0
dev: true
/execa@7.2.0:
resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==}
engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0}
dependencies:
cross-spawn: 7.0.3
get-stream: 6.0.1
human-signals: 4.3.1
is-stream: 3.0.0
merge-stream: 2.0.0
npm-run-path: 5.1.0
onetime: 6.0.0
signal-exit: 3.0.7
strip-final-newline: 3.0.0
dev: true
/express@4.18.2:
resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
engines: {node: '>= 0.10.0'}
@@ -4211,6 +4338,10 @@ packages:
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
dev: true
/fast-glob@3.3.1:
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
engines: {node: '>=8.6.0'}
@@ -4733,6 +4864,11 @@ packages:
engines: {node: '>=10.17.0'}
dev: true
/human-signals@4.3.1:
resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
engines: {node: '>=14.18.0'}
dev: true
/iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -4756,6 +4892,10 @@ packages:
postcss: 8.4.27
dev: true
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
/ignore@5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'}
@@ -4879,6 +5019,12 @@ packages:
hasBin: true
dev: true
/is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
dev: true
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -4889,6 +5035,14 @@ packages:
dependencies:
is-extglob: 2.1.1
/is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
hasBin: true
dependencies:
is-docker: 3.0.0
dev: true
/is-negative-zero@2.0.2:
resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
engines: {node: '>= 0.4'}
@@ -4960,6 +5114,11 @@ packages:
engines: {node: '>=8'}
dev: true
/is-stream@3.0.0:
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/is-string@1.0.7:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
engines: {node: '>= 0.4'}
@@ -5261,6 +5420,11 @@ packages:
engines: {node: '>=6'}
dev: true
/mimic-fn@4.0.0:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
dev: true
/minimalistic-assert@1.0.1:
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
dev: true
@@ -5331,6 +5495,13 @@ packages:
tslib: 2.6.1
dev: true
/node-cache@5.1.2:
resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==}
engines: {node: '>= 8.0.0'}
dependencies:
clone: 2.1.2
dev: false
/node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
engines: {node: '>= 6.13.0'}
@@ -5356,6 +5527,13 @@ packages:
path-key: 3.1.1
dev: true
/npm-run-path@5.1.0:
resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
path-key: 4.0.0
dev: true
/nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies:
@@ -5461,6 +5639,13 @@ packages:
mimic-fn: 2.1.0
dev: true
/onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
dependencies:
mimic-fn: 4.0.0
dev: true
/open@8.4.2:
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
engines: {node: '>=12'}
@@ -5470,6 +5655,16 @@ packages:
is-wsl: 2.2.0
dev: true
/open@9.1.0:
resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==}
engines: {node: '>=14.16'}
dependencies:
default-browser: 4.0.0
define-lazy-prop: 3.0.0
is-inside-container: 1.0.0
is-wsl: 2.2.0
dev: true
/optionator@0.9.3:
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
engines: {node: '>= 0.8.0'}
@@ -5607,6 +5802,11 @@ packages:
engines: {node: '>=8'}
dev: true
/path-key@4.0.0:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
engines: {node: '>=12'}
dev: true
/path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
@@ -6124,9 +6324,16 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
/prettier@2.8.8:
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
engines: {node: '>=10.13.0'}
/prettier-linter-helpers@1.0.0:
resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
engines: {node: '>=6.0.0'}
dependencies:
fast-diff: 1.3.0
dev: true
/prettier@3.0.2:
resolution: {integrity: sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==}
engines: {node: '>=14'}
hasBin: true
dev: true
@@ -6477,6 +6684,13 @@ packages:
glob: 7.2.3
dev: true
/run-applescript@5.0.0:
resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==}
engines: {node: '>=12'}
dependencies:
execa: 5.1.1
dev: true
/run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
@@ -6854,6 +7068,11 @@ packages:
engines: {node: '>=6'}
dev: true
/strip-final-newline@3.0.0:
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
engines: {node: '>=12'}
dev: true
/strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -6907,6 +7126,14 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/synckit@0.8.5:
resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
engines: {node: ^14.18.0 || >=16.0.0}
dependencies:
'@pkgr/utils': 2.4.2
tslib: 2.6.1
dev: true
/tailwindcss@3.3.3:
resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
engines: {node: '>=14.0.0'}
@@ -6999,6 +7226,11 @@ packages:
resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==}
dev: true
/titleize@3.0.0:
resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==}
engines: {node: '>=12'}
dev: true
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@@ -7171,6 +7403,11 @@ packages:
engines: {node: '>= 0.8'}
dev: true
/untildify@4.0.0:
resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
engines: {node: '>=8'}
dev: true
/update-browserslist-db@1.0.11(browserslist@4.21.10):
resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
hasBin: true

View File

@@ -1,6 +1,6 @@
import React, { MouseEventHandler, ReactElement, ReactNode } from "react";
import classNames from "classnames";
import "./icon.scss";
import React, { MouseEventHandler, ReactElement, ReactNode } from 'react';
import classNames from 'classnames';
import './icon.scss';
type Props = {
url?: string;
@@ -12,16 +12,16 @@ type Props = {
};
export default function Icon(props: Props): ReactElement {
const { url, size = 1, className = "", fa, onClick, children } = props;
const { url, size = 1, className = '', fa, onClick, children } = props;
return (
<div
className={classNames(
"bg-contain bg-center bg-no-repeat icon",
'bg-contain bg-center bg-no-repeat icon',
{
"cursor-pointer": onClick,
'cursor-pointer': onClick,
},
className
className,
)}
style={{
backgroundImage: url ? `url(${url})` : undefined,

View File

@@ -1,8 +1,8 @@
import React, { MouseEventHandler, ReactElement, ReactNode } from "react";
import ReactDOM from "react-dom";
import "./modal.scss";
import Icon from "../Icon";
import classNames from "classnames";
import React, { MouseEventHandler, ReactElement, ReactNode } from 'react';
import ReactDOM from 'react-dom';
import './modal.scss';
import Icon from '../Icon';
import classNames from 'classnames';
type Props = {
className?: string;
@@ -13,13 +13,13 @@ type Props = {
export default function Modal(props: Props): ReactElement {
const { className, onClose, children } = props;
const modalRoot = document.querySelector("#modal-root");
const modalRoot = document.querySelector('#modal-root');
if (!modalRoot) return <></>;
return ReactDOM.createPortal(
<div
className={classNames("bg-black bg-opacity-80", "modal__overlay")}
className={classNames('bg-black bg-opacity-80', 'modal__overlay')}
onClick={(e) => {
e.stopPropagation();
onClose && onClose(e);
@@ -32,7 +32,7 @@ export default function Modal(props: Props): ReactElement {
{children}
</div>
</div>,
modalRoot
modalRoot,
);
}
@@ -43,15 +43,15 @@ type HeaderProps = {
export function ModalHeader(props: HeaderProps): ReactElement {
return (
<div className={classNames("border-b modal__header border-gray-100")}>
<div className={classNames('border-b modal__header border-gray-100')}>
<div className="modal__header__title">{props.children}</div>
<div className="modal__header__content">
{props.onClose && (
<div
className={classNames(
"flex flex-row items-center justify-center",
"p-2 rounded-full opacity-50",
"hover:opacity-100 text-black"
'flex flex-row items-center justify-center',
'p-2 rounded-full opacity-50',
'hover:opacity-100 text-black',
)}
>
<Icon fa="fas fa-times" size={1} onClick={props.onClose} />
@@ -69,7 +69,7 @@ type ContentProps = {
export function ModalContent(props: ContentProps): ReactElement {
return (
<div className={classNames("modal__content", props.className)}>
<div className={classNames('modal__content', props.className)}>
{props.children}
</div>
);
@@ -84,8 +84,8 @@ export function ModalFooter(props: FooterProps): ReactElement {
return (
<div
className={classNames(
"border-t modal__footer border-gray-100",
props.className
'border-t modal__footer border-gray-100',
props.className,
)}
>
{props.children}

View File

@@ -4,9 +4,12 @@ import React, {
useCallback,
useEffect,
useState,
} from "react";
import { BackgroundActiontype, RequestLog } from "../../pages/Background/actionTypes";
import classNames from "classnames";
} from 'react';
import {
BackgroundActiontype,
RequestLog,
} from '../../pages/Background/actionTypes';
import classNames from 'classnames';
import {
Navigate,
Route,
@@ -14,8 +17,8 @@ import {
useLocation,
useNavigate,
useParams,
} from "react-router";
import Icon from "../Icon";
} from 'react-router';
import Icon from '../Icon';
type Props = {
data: RequestLog | null;
@@ -33,7 +36,7 @@ export default function RequestDetail(props: Props): ReactElement {
<Icon
className="cursor-point text-slate-400 hover:text-slate-700"
fa="fa-solid fa-xmark"
onClick={() => navigate("/requests")}
onClick={() => navigate('/requests')}
/>
<RequestDetailsHeaderTab path="/headers">
Headers
@@ -44,7 +47,7 @@ export default function RequestDetail(props: Props): ReactElement {
<RequestDetailsHeaderTab path="/response">
Response
</RequestDetailsHeaderTab>
<button
<button
className="absolute right-2 bg-primary/[0.9] text-white font-bold px-2 py-0.5 hover:bg-primary/[0.8] active:bg-primary"
onClick={async () => {
await chrome.runtime.sendMessage({
@@ -76,11 +79,11 @@ function RequestDetailsHeaderTab(props: {
const selected = loc.pathname.includes(props.path);
return (
<div
className={classNames("font-bold", {
"text-slate-700 cursor-default": selected,
"text-slate-400 hover:text-slate-500 cursor-pointer": !selected,
className={classNames('font-bold', {
'text-slate-700 cursor-default': selected,
'text-slate-400 hover:text-slate-500 cursor-pointer': !selected,
})}
onClick={() => navigate("/requests/" + params.requestId + props.path)}
onClick={() => navigate('/requests/' + params.requestId + props.path)}
>
{props.children}
</div>
@@ -236,12 +239,12 @@ function WebResponse(props: Props): ReactElement {
method: data.method,
headers: data.requestHeaders.reduce(
(acc: { [key: string]: string }, h: chrome.webRequest.HttpHeader) => {
if (typeof h.name !== "undefined" && typeof h.value !== "undefined") {
if (typeof h.name !== 'undefined' && typeof h.value !== 'undefined') {
acc[h.name] = h.value;
}
return acc;
},
{}
{},
),
body: data?.requestBody,
};
@@ -254,21 +257,21 @@ function WebResponse(props: Props): ReactElement {
setResponse(resp);
const contentType =
resp?.headers.get("content-type") || resp?.headers.get("Content-Type");
resp?.headers.get('content-type') || resp?.headers.get('Content-Type');
if (contentType?.includes("application/json")) {
if (contentType?.includes('application/json')) {
resp.json().then((json) => {
if (json) {
setJSON(json);
}
});
} else if (contentType?.includes("text")) {
} else if (contentType?.includes('text')) {
resp.text().then((_text) => {
if (_text) {
setText(_text);
}
});
} else if (contentType?.includes("image")) {
} else if (contentType?.includes('image')) {
resp.blob().then((blob) => {
if (blob) {
setImg(URL.createObjectURL(blob));

View File

@@ -1,13 +1,13 @@
import React, { ReactElement, useCallback, useState } from "react";
import React, { ReactElement, useCallback, useState } from 'react';
import {
BackgroundActiontype,
RequestLog,
} from "../../pages/Background/actionTypes";
import { useNavigate } from "react-router";
import Fuse from "fuse.js";
import Icon from "../Icon";
import { useDispatch } from "react-redux";
import { setRequests } from "../../reducers/requests";
} from '../../pages/Background/actionTypes';
import { useNavigate } from 'react-router';
import Fuse from 'fuse.js';
import Icon from '../Icon';
import { useDispatch } from 'react-redux';
import { setRequests } from '../../reducers/requests';
type Props = {
requests: RequestLog[];
@@ -17,7 +17,7 @@ export default function RequestTable(props: Props): ReactElement {
const { requests } = props;
const navigate = useNavigate();
const dispatch = useDispatch();
const [query, setQuery] = useState("");
const [query, setQuery] = useState('');
const fuse = new Fuse(requests, {
isCaseSensitive: true,
@@ -28,13 +28,13 @@ export default function RequestTable(props: Props): ReactElement {
includeMatches: true,
ignoreLocation: true,
keys: [
{ name: "method", weight: 2 },
{ name: "type", weight: 2 },
{ name: "requestHeaders.name", weight: 1 },
{ name: "requestHeaders.value", weight: 1 },
{ name: "responseHeaders.name", weight: 1 },
{ name: "responseHeaders.value", weight: 1 },
{ name: "url", weight: 1 },
{ name: 'method', weight: 2 },
{ name: 'type', weight: 2 },
{ name: 'requestHeaders.name', weight: 1 },
{ name: 'requestHeaders.value', weight: 1 },
{ name: 'responseHeaders.name', weight: 1 },
{ name: 'responseHeaders.value', weight: 1 },
{ name: 'url', weight: 1 },
],
});
@@ -79,7 +79,7 @@ export default function RequestTable(props: Props): ReactElement {
{list.map((r) => (
<tr
key={r.requestId}
onClick={() => navigate("/requests/" + r.requestId)}
onClick={() => navigate('/requests/' + r.requestId)}
className="cursor-pointer hover:bg-slate-100"
>
<td className="border border-slate-200 align-top py-1 px-2 whitespace-nowrap w-2/12">

2
src/global.d.ts vendored
View File

@@ -1,4 +1,4 @@
declare module "*.png" {
declare module '*.png' {
const value: any;
export = value;
}

View File

@@ -1,8 +1,8 @@
export enum BackgroundActiontype {
get_requests = "get_requests",
clear_requests = "clear_requests",
push_action = "push_action",
test_wasm = "test_wasm",
get_requests = 'get_requests',
clear_requests = 'clear_requests',
push_action = 'push_action',
test_wasm = 'test_wasm',
}
export type BackgroundAction = {

View File

@@ -1,130 +1,156 @@
import { BackgroundActiontype, RequestLog } from "./actionTypes";
import { Mutex } from "async-mutex";
import { addRequest } from "../../reducers/requests";
import { BackgroundActiontype, RequestLog } from './actionTypes';
import { Mutex } from 'async-mutex';
import NodeCache from 'node-cache';
import { addRequest } from '../../reducers/requests';
let RequestsLogs: {
[tabId: string]: {
[requestId: string]: RequestLog;
};
[tabId: string]: NodeCache;
} = {};
const mutex = new Mutex();
const cache = new NodeCache({
stdTTL: 60 * 5, // default 5m TTL
maxKeys: 1000000,
});
(chrome as any).offscreen.createDocument({
url: 'offscreen.html',
reasons: ['WORKERS'],
justification: 'workers for multithreading',
});
chrome.tabs.onActivated.addListener((tabs) => {
RequestsLogs[tabs.tabId] = RequestsLogs[tabs.tabId] || new NodeCache({
stdTTL: 60 * 5, // default 5m TTL
maxKeys: 1000000,
});
});
chrome.tabs.onRemoved.addListener((tab) => {
delete RequestsLogs[tab];
});
(async () => {
// @ts-ignore
chrome.offscreen.createDocument({
url: "offscreen.html",
reasons: ["WORKERS"],
justification: "workers for multithreading",
});
chrome.tabs.onActivated.addListener((tabs) => {
const tab = RequestsLogs[tabs.tabId];
RequestsLogs = {
[tabs.tabId]: tab,
};
});
chrome.webRequest.onSendHeaders.addListener(
(details) => {
mutex.runExclusive(async () => {
const { method } = details;
const { method, tabId, requestId } = details;
if (method !== "OPTIONS") {
RequestsLogs[details.tabId] = RequestsLogs[details.tabId] || {};
RequestsLogs[details.tabId][details.requestId] = {
...RequestsLogs[details.tabId][details.requestId],
method: details.method as "GET" | "POST",
if (method !== 'OPTIONS') {
RequestsLogs[tabId] = RequestsLogs[tabId] || new NodeCache({
stdTTL: 60 * 5, // default 5m TTL
maxKeys: 1000000,
});
const existing = RequestsLogs[tabId].get<RequestLog>(requestId);
RequestsLogs[tabId].set(requestId, {
...existing,
method: details.method as 'GET' | 'POST',
type: details.type,
url: details.url,
initiator: details.initiator || null,
requestHeaders: details.requestHeaders || [],
tabId: details.tabId,
requestId: details.requestId,
};
tabId: tabId,
requestId: requestId,
});
}
});
},
{
urls: ["<all_urls>"],
urls: ['<all_urls>'],
},
["requestHeaders"]
['requestHeaders'],
);
chrome.webRequest.onBeforeRequest.addListener(
(details) => {
mutex.runExclusive(async () => {
const { method, requestBody } = details;
if (method === "OPTIONS") return;
const { method, requestBody, tabId, requestId } = details;
if (method === 'OPTIONS') return;
if (requestBody) {
RequestsLogs[tabId] = RequestsLogs[tabId] || new NodeCache({
stdTTL: 60 * 5, // default 5m TTL
maxKeys: 1000000,
});
const existing = RequestsLogs[tabId].get<RequestLog>(requestId);
if (requestBody.raw && requestBody.raw[0]?.bytes) {
const bodyString = String.fromCharCode.apply(
null,
new Uint8Array(requestBody.raw[0].bytes) as any
);
try {
RequestsLogs[details.tabId].set(requestId, {
...existing,
requestBody: Buffer.from(requestBody.raw[0].bytes).toString('utf-8'),
});
} catch (e) {
console.error(e);
}
RequestsLogs[details.tabId] = RequestsLogs[details.tabId] || {};
RequestsLogs[details.tabId][details.requestId] = {
...RequestsLogs[details.tabId][details.requestId],
requestBody: bodyString,
};
} else if (requestBody.formData) {
RequestsLogs[details.tabId] = RequestsLogs[details.tabId] || {};
RequestsLogs[details.tabId][details.requestId] = {
...RequestsLogs[details.tabId][details.requestId],
RequestsLogs[details.tabId].set(requestId, {
...existing,
formData: requestBody.formData,
};
});
}
}
});
},
{
urls: ["<all_urls>"],
urls: ['<all_urls>'],
},
["requestBody"]
['requestBody'],
);
chrome.webRequest.onResponseStarted.addListener(
(details) => {
mutex.runExclusive(async () => {
const { method, responseHeaders } = details;
if (method === "OPTIONS") return;
const { method, responseHeaders, tabId, requestId, } = details;
if (method === 'OPTIONS') return;
RequestsLogs[details.tabId] = RequestsLogs[details.tabId] || {};
RequestsLogs[tabId] = RequestsLogs[tabId] || new NodeCache({
stdTTL: 60 * 5, // default 5m TTL
maxKeys: 1000000,
});
RequestsLogs[details.tabId][details.requestId] = {
...RequestsLogs[details.tabId][details.requestId],
const existing = RequestsLogs[tabId].get<RequestLog>(requestId);
const newLog: RequestLog = {
requestHeaders: [],
...existing,
method: details.method,
type: details.type,
url: details.url,
initiator: details.initiator || null,
tabId: details.tabId,
requestId: details.requestId,
tabId: tabId,
requestId: requestId,
responseHeaders,
};
RequestsLogs[tabId].set(requestId, newLog);
await chrome.runtime.sendMessage({
type: BackgroundActiontype.push_action,
data: {
tabId: details.tabId,
request: RequestsLogs[details.tabId][details.requestId],
request: newLog,
},
action: addRequest(RequestsLogs[details.tabId][details.requestId]),
action: addRequest(newLog),
});
});
},
{
urls: ["<all_urls>"],
urls: ['<all_urls>'],
},
["responseHeaders"]
['responseHeaders'],
);
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
switch (request.type) {
case BackgroundActiontype.get_requests: {
RequestsLogs[request.data] = RequestsLogs[request.data] || {};
return sendResponse(Object.values(RequestsLogs[request.data]));
const keys = RequestsLogs[request.data]?.keys() || [];
const data = keys.map((key) => RequestsLogs[request.data]?.get(key));
return sendResponse((data));
}
case BackgroundActiontype.clear_requests: {
RequestsLogs = {};

View File

@@ -1,6 +1,9 @@
console.log("Content script works!");
console.log("Must reload extension for modifications to take effect.");
window.onerror = (error) => {
console.error(error);
console.log('error');
console.log(error);
};
(async () => {
console.log('Content script works!');
console.log('Must reload extension for modifications to take effect.');
})();

View File

@@ -1,10 +1,10 @@
import React, { MouseEventHandler, ReactElement, ReactNode } from "react";
import Icon from "../../components/Icon";
import classNames from "classnames";
import { useNavigate } from "react-router";
import { useActiveTabUrl, useRequests } from "../../reducers/requests";
import { Link } from "react-router-dom";
import { filterByBookmarks } from "../../../utils/bookmark";
import React, { MouseEventHandler, ReactElement, ReactNode } from 'react';
import Icon from '../../components/Icon';
import classNames from 'classnames';
import { useNavigate } from 'react-router';
import { useActiveTabUrl, useRequests } from '../../reducers/requests';
import { Link } from 'react-router-dom';
import { filterByBookmarks } from '../../../utils/bookmark';
export default function Home(): ReactElement {
const requests = useRequests();
@@ -15,18 +15,18 @@ export default function Home(): ReactElement {
return (
<>
<div className="flex flex-row flex-nowrap justify-center gap-8 my-8">
<NavButton fa="fa-solid fa-table" onClick={() => navigate("/requests")}>
<NavButton fa="fa-solid fa-table" onClick={() => navigate('/requests')}>
<div>Requests</div>
<div>{`(${requests.length})`}</div>
</NavButton>
<NavButton
fa="fa-solid fa-magnifying-glass"
onClick={() => navigate("/verify")}
onClick={() => navigate('/verify')}
disabled
>
Verify
</NavButton>
<NavButton fa="fa-solid fa-list" onClick={() => navigate("/history")}>
<NavButton fa="fa-solid fa-list" onClick={() => navigate('/history')}>
History
</NavButton>
</div>
@@ -94,14 +94,14 @@ function NavButton(props: {
return (
<button
className={classNames(
"flex flex-col flex-nowrap items-center justify-center",
"text-white rounded-full p-4 h-24 w-24 gap-1",
'flex flex-col flex-nowrap items-center justify-center',
'text-white rounded-full p-4 h-24 w-24 gap-1',
{
"bg-primary/[.8] hover:bg-primary/[.7] active:bg-primary":
'bg-primary/[.8] hover:bg-primary/[.7] active:bg-primary':
!props.disabled,
"bg-primary/[.5]": props.disabled,
'bg-primary/[.5]': props.disabled,
},
props.className
props.className,
)}
onClick={props.onClick}
disabled={props.disabled}

View File

@@ -1,25 +1,27 @@
import React, { useEffect } from "react";
import * as Comlink from "comlink";
import { BackgroundActiontype } from "../Background/actionTypes";
import React, { useEffect } from 'react';
import * as Comlink from 'comlink';
import { BackgroundActiontype } from '../Background/actionTypes';
const Offscreen = () => {
useEffect(() => {
(async function offscreenloaded() {
console.log("offscreen loaded - spawning worker from worker.ts");
console.log('offscreen loaded - spawning worker from worker.ts');
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
switch (request.type) {
case BackgroundActiontype.test_wasm: {
const Wasm: any = Comlink.wrap(
new Worker(new URL("./worker.ts", import.meta.url)));
await new Wasm();
return sendResponse();
chrome.runtime.onMessage.addListener(
async (request, sender, sendResponse) => {
switch (request.type) {
case BackgroundActiontype.test_wasm: {
const Wasm: any = Comlink.wrap(
new Worker(new URL('./worker.ts', import.meta.url)),
);
await new Wasm();
return sendResponse();
}
default:
break;
}
default:
break;
}
})
},
);
})();
}, []);

View File

@@ -1,8 +1,8 @@
import React from "react";
import { createRoot } from "react-dom/client";
import React from 'react';
import { createRoot } from 'react-dom/client';
import Offscreen from "./Offscreen";
import Offscreen from './Offscreen';
const container = document.getElementById("app-container");
const container = document.getElementById('app-container');
const root = createRoot(container!);
root.render(<Offscreen />);

View File

@@ -1,21 +1,24 @@
import * as Comlink from "comlink";
import init, { prover } from "../../../wasm/prover/pkg/tlsn_extension_rs";
import * as Comlink from 'comlink';
import init, { prover } from '../../../wasm/prover/pkg/tlsn_extension_rs';
class Test {
constructor() {
console.log("worker test module initiated.");
console.log('worker test module initiated.');
this.test();
}
async test() {
console.log('start');
console.log("!@# navigator.hardwareConcurrency=", navigator.hardwareConcurrency)
console.log(
'!@# navigator.hardwareConcurrency=',
navigator.hardwareConcurrency,
);
await init();
// await initThreadPool(2);
// console.log("!@# result js=", DATA.reduce((sum, n) => sum + n, 0));
// console.log("!@# result rs=", sum(new Int32Array(DATA)));
const resProver = await prover();
console.log("!@# resProver=", resProver)
console.log('!@# resProver=', resProver);
}
}

View File

@@ -1,5 +1,5 @@
import React from "react";
import "./Options.css";
import React from 'react';
import './Options.css';
interface Props {
title: string;

View File

@@ -1,9 +1,9 @@
import React from "react";
import { createRoot } from "react-dom/client";
import React from 'react';
import { createRoot } from 'react-dom/client';
import Options from "./Options";
import "./index.css";
import Options from './Options';
import './index.css';
const container = document.getElementById("app-container");
const container = document.getElementById('app-container');
const root = createRoot(container!); // createRoot(container!) if you use TypeScript
root.render(<Options title={"Settings"} />);
root.render(<Options title={'Settings'} />);

View File

@@ -1,17 +1,17 @@
import React, { useEffect } from "react";
import { Navigate, Route, Routes, useNavigate } from "react-router";
import { useDispatch } from "react-redux";
import React, { useEffect } from 'react';
import { Navigate, Route, Routes, useNavigate } from 'react-router';
import { useDispatch } from 'react-redux';
import {
setActiveTab,
setRequests,
useActiveTab,
useActiveTabUrl,
} from "../../reducers/requests";
import { BackgroundActiontype } from "../Background/actionTypes";
import Requests from "../Requests";
import Request from "../Requests/Request";
import Home from "../Home";
import logo from "../../assets/img/icon-128.png";
} from '../../reducers/requests';
import { BackgroundActiontype } from '../Background/actionTypes';
import Requests from '../Requests';
import Request from '../Requests/Request';
import Home from '../Home';
import logo from '../../assets/img/icon-128.png';
const Popup = () => {
const dispatch = useDispatch();
@@ -44,7 +44,7 @@ const Popup = () => {
className="absolute left-2 h-5 cursor-pointer"
src={logo}
alt="logo"
onClick={() => navigate("/")}
onClick={() => navigate('/')}
/>
<div className="absolute right-2 flex flex-nowrap flex-row items-center gap-1 justify-center w-fit">
<img

View File

@@ -1,14 +1,14 @@
import React from "react";
import { createRoot } from "react-dom/client";
import { HashRouter } from "react-router-dom";
import React from 'react';
import { createRoot } from 'react-dom/client';
import { HashRouter } from 'react-router-dom';
import Popup from "./Popup";
import "./index.scss";
import { Provider } from "react-redux";
import store from "../../utils/store";
import { BackgroundActiontype } from "../Background/actionTypes";
import Popup from './Popup';
import './index.scss';
import { Provider } from 'react-redux';
import store from '../../utils/store';
import { BackgroundActiontype } from '../Background/actionTypes';
const container = document.getElementById("app-container");
const container = document.getElementById('app-container');
const root = createRoot(container!); // createRoot(container!) if you use TypeScript
chrome.runtime.onMessage.addListener((request) => {
@@ -27,5 +27,5 @@ root.render(
<HashRouter>
<Popup />
</HashRouter>
</Provider>
</Provider>,
);

View File

@@ -1,7 +1,7 @@
import React, { ReactElement } from "react";
import RequestDetail from "../../components/RequestDetail";
import { useParams } from "react-router";
import { useRequest } from "../../reducers/requests";
import React, { ReactElement } from 'react';
import RequestDetail from '../../components/RequestDetail';
import { useParams } from 'react-router';
import { useRequest } from '../../reducers/requests';
export default function Request(): ReactElement {
const params = useParams<{ requestId: string }>();

View File

@@ -1,6 +1,6 @@
import React, { ReactElement } from "react";
import RequestTable from "../../components/RequestTable";
import { useRequests } from "../../reducers/requests";
import React, { ReactElement } from 'react';
import RequestTable from '../../components/RequestTable';
import { useRequests } from '../../reducers/requests';
export default function Requests(): ReactElement {
const requests = useRequests();

View File

@@ -1,5 +1,5 @@
import { combineReducers } from "redux";
import requests from "./requests";
import { combineReducers } from 'redux';
import requests from './requests';
const rootReducer = combineReducers({
requests,

View File

@@ -1,12 +1,12 @@
import { RequestLog } from "../pages/Background/actionTypes";
import { useSelector } from "react-redux";
import { AppRootState } from "./index";
import deepEqual from "fast-deep-equal";
import { RequestLog } from '../pages/Background/actionTypes';
import { useSelector } from 'react-redux';
import { AppRootState } from './index';
import deepEqual from 'fast-deep-equal';
enum ActionType {
"/requests/setRequests" = "/requests/setRequests",
"/requests/addRequest" = "/requests/addRequest",
"/requests/setActiveTab" = "/requests/setActiveTab",
'/requests/setRequests' = '/requests/setRequests',
'/requests/addRequest' = '/requests/addRequest',
'/requests/setActiveTab' = '/requests/setActiveTab',
}
type Action<payload> = {
@@ -29,28 +29,28 @@ const initialState: State = {
};
export const setRequests = (requests: RequestLog[]): Action<RequestLog[]> => ({
type: ActionType["/requests/setRequests"],
type: ActionType['/requests/setRequests'],
payload: requests,
});
export const setActiveTab = (
activeTab: chrome.tabs.Tab | null
activeTab: chrome.tabs.Tab | null,
): Action<chrome.tabs.Tab | null> => ({
type: ActionType["/requests/setActiveTab"],
type: ActionType['/requests/setActiveTab'],
payload: activeTab,
});
export const addRequest = (request: RequestLog): Action<RequestLog> => ({
type: ActionType["/requests/addRequest"],
type: ActionType['/requests/addRequest'],
payload: request,
});
export default function requests(
state = initialState,
action: Action<any>
action: Action<any>,
): State {
switch (action.type) {
case ActionType["/requests/setRequests"]:
case ActionType['/requests/setRequests']:
return {
...state,
map: {
@@ -59,16 +59,16 @@ export default function requests(
acc[req.requestId] = req;
return acc;
},
{}
{},
),
},
};
case ActionType["/requests/setActiveTab"]:
case ActionType['/requests/setActiveTab']:
return {
...state,
activeTab: action.payload,
};
case ActionType["/requests/addRequest"]:
case ActionType['/requests/addRequest']:
return {
...state,
map: {

View File

@@ -1,15 +1,15 @@
import { applyMiddleware, createStore } from "redux";
import thunk from "redux-thunk";
import { createLogger } from "redux-logger";
import rootReducer from "../reducers";
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';
import rootReducer from '../reducers';
const createStoreWithMiddleware =
process.env.NODE_ENV === "development"
process.env.NODE_ENV === 'development'
? applyMiddleware(
thunk,
createLogger({
collapsed: true,
})
}),
)(createStore)
: applyMiddleware(thunk)(createStore);

View File

@@ -1,10 +1,10 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {
colors: {
primary: "#243f5f",
primary: '#243f5f',
},
},
},

View File

@@ -1,5 +1,5 @@
import bookmarks from "./bookmarks.json";
import { RequestLog } from "../../src/pages/Background/actionTypes";
import bookmarks from './bookmarks.json';
import { RequestLog } from '../../src/pages/Background/actionTypes';
type Bookmark = {
url: string;

View File

@@ -1,25 +1,25 @@
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = "production";
process.env.NODE_ENV = "production";
process.env.ASSET_PATH = "/";
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
process.env.ASSET_PATH = '/';
var webpack = require("webpack"),
path = require("path"),
fs = require("fs"),
config = require("../webpack.config"),
ZipPlugin = require("zip-webpack-plugin");
var webpack = require('webpack'),
path = require('path'),
fs = require('fs'),
config = require('../webpack.config'),
ZipPlugin = require('zip-webpack-plugin');
delete config.chromeExtensionBoilerplate;
config.mode = "production";
config.mode = 'production';
var packageInfo = JSON.parse(fs.readFileSync("package.json", "utf-8"));
var packageInfo = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
config.plugins = (config.plugins || []).concat(
new ZipPlugin({
filename: `${packageInfo.name}-${packageInfo.version}.zip`,
path: path.join(__dirname, "../", "zip"),
})
path: path.join(__dirname, '../', 'zip'),
}),
);
webpack(config, function (err) {

View File

@@ -1,5 +1,5 @@
// tiny wrapper with default env vars
module.exports = {
NODE_ENV: process.env.NODE_ENV || "development",
NODE_ENV: process.env.NODE_ENV || 'development',
PORT: process.env.PORT || 3000,
};

View File

@@ -1,13 +1,13 @@
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = "development";
process.env.NODE_ENV = "development";
process.env.ASSET_PATH = "/";
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
process.env.ASSET_PATH = '/';
var WebpackDevServer = require("webpack-dev-server"),
webpack = require("webpack"),
config = require("../webpack.config"),
env = require("./env"),
path = require("path");
var WebpackDevServer = require('webpack-dev-server'),
webpack = require('webpack'),
config = require('../webpack.config'),
env = require('./env'),
path = require('path');
var options = config.chromeExtensionBoilerplate || {};
var excludeEntriesToHotReload = options.notHotReload || [];
@@ -15,7 +15,7 @@ var excludeEntriesToHotReload = options.notHotReload || [];
for (var entryName in config.entry) {
if (excludeEntriesToHotReload.indexOf(entryName) === -1) {
config.entry[entryName] = [
"webpack/hot/dev-server",
'webpack/hot/dev-server',
`webpack-dev-server/client?hot=true&hostname=localhost&port=${env.PORT}`,
].concat(config.entry[entryName]);
}
@@ -31,24 +31,24 @@ var server = new WebpackDevServer(
hot: true,
liveReload: false,
client: {
webSocketTransport: "ws",
webSocketTransport: 'ws',
},
webSocketServer: "ws",
host: "localhost",
webSocketServer: 'ws',
host: 'localhost',
port: env.PORT,
static: {
directory: path.join(__dirname, "../build"),
directory: path.join(__dirname, '../build'),
},
devMiddleware: {
publicPath: `http://localhost:${env.PORT}/`,
writeToDisk: true,
},
headers: {
"Access-Control-Allow-Origin": "*",
'Access-Control-Allow-Origin': '*',
},
allowedHosts: "all",
allowedHosts: 'all',
},
compiler
compiler,
);
(async () => {

View File

@@ -209,6 +209,9 @@ var options = {
chunks: ["offscreen"],
cache: false,
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
].filter(Boolean),
infrastructureLogging: {
level: "info",