From f1058067268ce9724ee5c3a527c21e42c90574a1 Mon Sep 17 00:00:00 2001 From: Pavel Ivanov Date: Thu, 12 Dec 2024 05:05:40 +0200 Subject: [PATCH] chore: a lot of things ... --- .eslintrc.js | 33 +- .vscode/settings.json | 6 + package.json | 9 +- .../brave-react-scanner-extension-v1.0.0.zip | Bin 94903 -> 0 bytes .../chrome-react-scanner-extension-v1.0.0.zip | Bin 94903 -> 0 bytes ...firefox-react-scanner-extension-v1.0.0.zip | Bin 94959 -> 0 bytes packages/extension/package.json | 1 - packages/extension/src/content/graph.ts | 1166 +++++++++++++++++ packages/extension/src/content/index.ts | 2 + packages/extension/src/inject/index.ts | 3 +- packages/scan/.gitignore | 1 + packages/scan/package.json | 20 +- packages/scan/postcss.config.mjs | 6 + packages/scan/src/cli.mts | 4 +- packages/scan/src/core/index.ts | 95 +- packages/scan/src/core/monitor/index.ts | 5 +- packages/scan/src/core/monitor/params/next.ts | 39 +- packages/scan/src/core/monitor/performance.ts | 11 +- packages/scan/src/core/monitor/utils.ts | 2 +- .../core/web/assets/css/styles.tailwind.css | 405 ++++++ .../scan/src/core/web/assets/svgs/svgs.ts | 77 ++ .../src/core/web/components/icon/index.tsx | 50 + .../core/web/components/widget/constants.ts | 28 + .../src/core/web/components/widget/header.tsx | 148 +++ .../src/core/web/components/widget/helpers.ts | 25 + .../src/core/web/components/widget/index.tsx | 443 +++++++ .../web/components/widget/resize-handle.tsx | 149 +++ .../core/web/components/widget/toolbar.tsx | 245 ++++ .../src/core/web/components/widget/types.ts | 29 + .../inspect-element/inspect-state-machine.ts | 34 +- .../src/core/web/inspect-element/overlay.ts | 14 +- .../src/core/web/inspect-element/utils.ts | 10 +- .../core/web/inspect-element/view-state.ts | 187 +-- packages/scan/src/core/web/overlay.ts | 123 +- packages/scan/src/core/web/state.ts | 14 + packages/scan/src/core/web/toolbar.tsx | 1051 +++++---------- .../scan/src/core/web/{ => utils}/geiger.ts | 25 +- .../core/web/{utils.ts => utils/helpers.ts} | 37 + packages/scan/src/core/web/{ => utils}/log.ts | 4 +- .../scan/src/core/web/{ => utils}/outline.ts | 12 +- packages/scan/src/monitoring/next.ts | 1 - .../__tests__/general-cases.test.ts | 30 +- .../__tests__/react-patterns.test.ts | 10 +- .../react-component-name/__tests__/utils.ts | 2 +- .../scan/src/react-component-name/index.ts | 8 +- .../scan/src/react-component-name/rolldown.ts | 4 +- packages/scan/src/types.d.ts | 7 + packages/scan/tailwind.config.mjs | 114 ++ packages/scan/tsconfig.json | 40 +- packages/scan/tsup.config.ts | 24 +- packages/website/app/layout.tsx | 10 +- .../app/monitoring/(components)/waitlist.tsx | 14 +- packages/website/app/monitoring/page.tsx | 10 +- packages/website/app/page.tsx | 16 +- packages/website/components/cli.tsx | 20 +- packages/website/components/code.tsx | 2 +- packages/website/components/companies.tsx | 10 +- packages/website/components/footer.tsx | 4 +- packages/website/components/header.tsx | 4 +- packages/website/components/todo-demo.tsx | 22 +- packages/website/package.json | 4 +- pnpm-lock.yaml | 1013 ++++++++------ tsconfig.json | 5 +- 63 files changed, 4323 insertions(+), 1564 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 packages/extension/build/brave-react-scanner-extension-v1.0.0.zip delete mode 100644 packages/extension/build/chrome-react-scanner-extension-v1.0.0.zip delete mode 100644 packages/extension/build/firefox-react-scanner-extension-v1.0.0.zip create mode 100644 packages/extension/src/content/graph.ts create mode 100644 packages/scan/.gitignore create mode 100644 packages/scan/postcss.config.mjs create mode 100644 packages/scan/src/core/web/assets/css/styles.tailwind.css create mode 100644 packages/scan/src/core/web/assets/svgs/svgs.ts create mode 100644 packages/scan/src/core/web/components/icon/index.tsx create mode 100644 packages/scan/src/core/web/components/widget/constants.ts create mode 100644 packages/scan/src/core/web/components/widget/header.tsx create mode 100644 packages/scan/src/core/web/components/widget/helpers.ts create mode 100644 packages/scan/src/core/web/components/widget/index.tsx create mode 100644 packages/scan/src/core/web/components/widget/resize-handle.tsx create mode 100644 packages/scan/src/core/web/components/widget/toolbar.tsx create mode 100644 packages/scan/src/core/web/components/widget/types.ts create mode 100644 packages/scan/src/core/web/state.ts rename packages/scan/src/core/web/{ => utils}/geiger.ts (73%) rename packages/scan/src/core/web/{utils.ts => utils/helpers.ts} (60%) rename packages/scan/src/core/web/{ => utils}/log.ts (96%) rename packages/scan/src/core/web/{ => utils}/outline.ts (96%) create mode 100644 packages/scan/tailwind.config.mjs diff --git a/.eslintrc.js b/.eslintrc.js index 909614e6..ef0e8db7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,17 +1,21 @@ const { resolve } = require('node:path'); -const project = resolve(__dirname, 'tsconfig.json'); - module.exports = { root: true, extends: [ require.resolve('@vercel/style-guide/eslint/node'), require.resolve('@vercel/style-guide/eslint/browser'), require.resolve('@vercel/style-guide/eslint/typescript'), + 'plugin:tailwindcss/recommended', ], - ignorePatterns: ['**/dist/*', '**/test/*'], + ignorePatterns: ['**/dist/**', '**/node_modules/**', '**/test/**'], parserOptions: { - project, + project: [ + resolve(__dirname, 'tsconfig.json'), // Root tsconfig + resolve(__dirname, 'packages/scan/tsconfig.json'), // Scan package tsconfig + ], + ecmaVersion: 2020, + sourceType: 'module', }, rules: { '@typescript-eslint/explicit-function-return-type': 'off', @@ -39,7 +43,6 @@ module.exports = { '@typescript-eslint/no-unnecessary-condition': 'off', '@typescript-eslint/no-confusing-void-expression': 'off', '@typescript-eslint/require-await': 'off', - // '@typescript-eslint/no-floating-promises': ['error'], 'import/no-named-as-default': 'off', 'no-implicit-coercion': 'off', '@typescript-eslint/no-redundant-type-constituents': 'off', @@ -48,15 +51,31 @@ module.exports = { 'no-useless-return': 'off', 'func-names': 'off', '@typescript-eslint/prefer-for-of': 'off', - // 'no-implicit-coercion': 'off', '@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/array-type': ['error', { default: 'generic' }], }, settings: { 'import/resolver': { typescript: { - project, + project: [ + resolve(__dirname, 'tsconfig.json'), // Root tsconfig + resolve(__dirname, 'packages/scan/tsconfig.json'), // Scan package tsconfig + ], }, }, }, + overrides: [ + { + files: ['*.json'], + parser: 'jsonc-eslint-parser', + plugins: ['jsonc'], + rules: { + 'jsonc/no-comments': 'off', + }, + }, + { + files: ['*.tsx', '*.ts', '*.js'], + plugins: ['tailwindcss'], + }, + ], }; diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..c27be254 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.importModuleSpecifier": "non-relative", + "typescript.preferences.includePackageJsonAutoImports": "on" +} diff --git a/package.json b/package.json index 7bc5a728..ffc5d54b 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,16 @@ "eslint:fix": "eslint --fix packages/*" }, "devDependencies": { + "@types/node": "^22.10.2", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", "@vercel/style-guide": "^6.0.0", "eslint": "^8.57.1", - "prettier": "^3.3.3" + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-jsonc": "^2.18.2", + "eslint-plugin-tailwindcss": "^3.17.5", + "prettier": "^3.3.3", + "typescript": "5.4.5" }, "packageManager": "pnpm@9.1.0", "dependencies": { diff --git a/packages/extension/build/brave-react-scanner-extension-v1.0.0.zip b/packages/extension/build/brave-react-scanner-extension-v1.0.0.zip deleted file mode 100644 index 5949c6499026c7ddd87d3edf205329e9ade27f03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94903 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 z 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 Vu=ni&2ngl&t@C2Q~6mC8ybRjV%c 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

}G=WSOFj$W<>n5 zK}T^$`0^3`pB6zr#!H`H!?__UXSM6LlZh654?cdaTb*Ei+3kVOeyA3PlW7bDE-YkO zxj)Mh(;^&$9!GGWJBYtL{Y`Mwik_AP@-0Mg@! zG$&5rNtSfpYr(B*hLB^?qBqv$rKUcB=c%#SyS1R$^l*P5P+W!RSFGMCNo0^=16JXx z4=s866qb5ztp^w{dIKQku`prbSjZ^(ME4(L*jQbhvgB$%h2I;ytKonSrFUc`b4Hv6J?-<|t+>)gx&_K;pSIXIuQt+v#vI%KrxXt5s@N>gM{k5lm(! z9ZBRnFvkRI6r*)B%&CAwwp^iBEL&Pst*AIAO@EK=Y;0fWHXeOwd7(ClVDZ~mMx405 zOh5kxxQsSZ^#G&M9-N38n%m)wqAwpPz)Yt(;TYjxg#X@-A45qxLyZM0njZ!#JF^E_ zNKqo~5fXXbsqkL>*yoVO^$J|XQ0xZsGDH0>!zy0qo1FG$@r;Qj_d5bJk;#wjRA)4@ z-PXvqE(!H85?Fz&lQV)J?(K|P(csQvW#`{{O4SKBS$;)}h3x#~Rpir3w zkZ4Qd*3%S|#3(zmK(C4i^j1PNK3sZ`9yvu`Y-vbIu^Kh0x=d#N_9}xlH0qmzA{z$t zG)Ws>3n?b5_m=5k=xc*brWfZUmS~go&cOD+ZH_7dXQAWH2RJb_xne{Ajb}MYHzHWm z=K<>mcMoPP*mREq*kWQ=XPjX6bzs4jTPd+Ni^J59BNb5e=)N$2Xk_O>bMIIU-9C3ZQxS_CyDKp5>B{1zxmh=JlsgBY)f}f@{`m}8ImC2yA zznF7b_HZ2asc-YQdUifm3#TLTKm9ZExI?~@N)hL70Q4v-`j+(UO zO+#m>e5MtCln%g0MUUS`?kSh9(_K@NuNy&I#u%n1WO@1x4W;T*m zPbb6NR_sQ@*0dXM+bSeham;vpaaY@_lb&(j+pGtZb#g8(ImTt%utDOXD5D1JB>@L6 z9GKoW-!>J~N)$=CK+^H~O2tKF+z5XQkQcXUNhfgBAiT_mAE~IR;4dvwOCg$Et!#Ls z=m|J0SW_x=J4A$N&6^L;Bpc95DBPDhH^VYn5{8X+LdpX6x739TFSdI{wR#(K6hZNL z8G^$-fJWGJmXu!|3`f(g{xJ{IZ{9p+p*5Xq?}V`&T${=&67&*@XN-;*2!Z5dzO8w( z7U}j4);>%cir$YMG5qN@mE7U95&|JDy~{7p|+35(^77)-0|vi&D3Z zizJoYIK3vh=hp`*e$&E(Py?V2R)P@1uIg{`iMW=@W%36 zPAqL!uJt{g8~b&l&H=npwpmG(Q<^(zL3vWWK%DCY*ssAqzCmSHPNH z^(f4h0w(OFm#T8|5p)A3TKNL;eOAW`@`Dd59$(bIeG(Zy531G5ebo1OmFySwl_SR? zD`ivGhe*kfKvNXb>O3&Iyi}Gq)&C?Kfh@SP#SdEeRzIsHUaTY{p(Bn$Zu2XtzR2Uh z$Qv|)sY{8ji6ZgTZ!c4sf`MkN;sPa@T}*d4KS#-h@Pb@m?XskLG@LSFvmGl=SfyYQ zVTcmnWBOHglwUnZ74>M#Of`WkzB~ZH6f5sA#ZOvs$)Q9Kn#HP-&{@x4d`9M@7hP@n z^mL7G-zLWVKFAjJ1bc{qQZ5-hZfwY9PTakQcm(Y32&FYJ{E>$myMsqmO~f4DQNkNV zGXAB~EaUk?#)jVJ7FKIHrJO*|IG@(`g?e>Sns2wC+e^z2zB&5DG+M7wL(i{16Bw~s zt@fjf?6Zu&`n*4O@=oOwfdJ7XL|UxVg`u~6u#TIhKpNPUb|Jrh^Xivx#n$Q@J{oo} z_gdLc-wmym9?Y1fq94p14V|scd`tOzJwN{dkZS(x6*J&_c;4in4{*KiA0U|`;O;Rs zXd1LCB1CR|5fJlI)&x^FX9@b2*fEBmqU#$kty#s?&;`UyxS;_b~Ma8qFopI)JstFg3y^j34*ullr)nMm&&{pzk`!C2kvP%_TmZX z1|(**mZ$cX7|Bf}FTMXOi22C^wvGN=x0(;J*7z?1qk&Ign7={!EtkF|cUD`$x zwuyFAgSLn>#_)i&(ngEPh4dJOr%V zx4jE;RamEyuj=2>J5*oD#SHbmo>BGGp(GNb#phmaL@=|p2iaGspmcKot?Q3{I2J|< zFQXnDznNUQq5r4dv(%~#?Hp#k6xQM=_0yK$N6YS)Kr3P z`)aq|J>X6xk96-{<|pSdAERJ7JIDj&tJ|I*h_h`1pXRe4+PO{xI^*ppj{JVYvJJY9 zTT3CO0D&>-j8Au8XSSmn1l!&M1>m|_N|sowK`kRZN&T06+>h^$MQ?e1C6z&EgVw}$ z*EA4Ol+itKz81=JHu=$B{Ob|bJ?6t7cr^eUj)g`V7#~#G{EYN8@1Un7vj}T0M)uV! zTI&@?>StTa++~Arlg-YM{r%}$o1r1kfnsUbWhkdYa4vSpLlx?$F<75#S#fWGYW}4V z@lRE^?(Ki%qZi8;nq+3>D=k|GxTIz(Zt`TsJ#xrT+U!$AaSbIWg)%xml|A4t_$$R1 zZHt7phkY$RT5m3`y0vWJzmH02IpOwp%}-CVzZ;(`LF{1xYK@jwXN#E&cM9AtZzkLb zwPOYM)dGu>+9qG4q*m~1(N}4>0{-&;ZREZ6P4vIg6pDRwaGm5-G{MHiOmH7xZzYq= zVy>A=*)1qb7?2-LBRJ)dQFJJtB_o1;8+;__13BR6E}$I&CRd;iobZ>+vF!*w^|C{0 zKq_OfGw*;Cv*YJyEi@bjRbH9qBmt9}m=X)eMil6r#ZtFZYmLkD+n-pf9$gJjQK4+a zF|B#CaBI31X3X7DjWX-}31;aO6|X-m0~!X{+m(wg+dvyP*yrTZI`bo7WlFqF`VLaD z&2zp`q{4f$sr3b!MEV~pVx?C~(kG+meHxu+HLY}3cP~WH+tTNIe@1gR^+LkC>kl@W z2UzmH57G`TxvJWPqxc5iVv>Qz@>^+-CKZrI5}nii!Zd_-wpUwL?4O%RBx(hNxVWBF z6VjlzyQ71WAa7biTRLTz@}0xfb-oM}>n+M>dE1Jbk>(I_ogy5v;^+K84>_M6+yja!O-)uo(g693!>i zY>dPKDjO*LhAW2@Ze`w@GzcqLG+Vm>;HHIXy{mto!ZVO5OS!4#6^(Cm{cnuC`B-jn zSh&2y8J)dz=lIEuq}~8$vbCIm5I?Z73XIrXEw=-9si6f_UZ~!&z)w(N;#O3Q^KAKp z+A@h)o`xzAU4E#9s?n6xJ(d@l4h1Kf-Yd?4dYKYHq~NQ2Sh{ork?ytCE47NzNj^JcceYeL^3kfA}Vca0yJY&BIg~M zmiw9KwEt)u1A$KK-1WuN{n@ek7%6d4?y3m6T!-^_9i_|4xwN%PrNgb(RC-pH*S3(i zixO9R^}tw^XEg?o?naPN7H);t*BV%k+$H;S*Fx`!Gven z_#tS!!Aw8D$uShTB!aztz|YpOv{J+{IE5R6bUS(hEy}FsQp{ol+V6VtSK{tVn6b6Z z%DqU>qjo2zN0tD32Ho5pcwP4BpQNU4pQW~19<3$fuT8R^kdoOL#{JM5 zH1K>Y2Vk=$);vN_N9}Pxv-=7e!aG?rn<9ASjT$+sPsZ0Vuuc8j!sBUuGzDWPRLG`GavdG`^!>40Wj3B!WxWNUa#OA3 zVnjW0im|ha?SIEy z^kD@Um@V>~dZGXbfcYP7^4H+CbtN{%H3}wfVgCH~~mEJ~TJ}&ySjKu$?)5a%i7rW_hmi?8Z>_ zd5={RR7gZu7nTn}4y#t=FxkPEZhTj`YZHRsvq(}UDAL@vjx<<5r8x4?J8@*87y>?q z%5RsJ?W{_sVez5$x&%Q^;drdd8Qfnp>DILwMfC9532|mzmoahyPa=$cqM>zk-ZAp$ z5$%pjLpOw8q+>FWTp*41fXF?*_>KnJSE7U{Rv{P|!F^{k!Q+x4140#mdihR9`Nw38 zqS2Z&`r*oulFsXa1ii>8%?uwtVTo&Ef`b+uGmi8~#hr!XfrA!FC|;n{uh(8gJ4`p> zxdB$4f-=FP;nMsZ>C(B+Q$ImbAlEKMwVg#GlSxApZFmLQPn!R$jY6Lx_p3fU6%j`6 z5#k$@LOE0`7kwM#@7#_m&t?t~c#WsySKskVSJll~@82Q+EroLiDif&QNk*ah;m5rH;pbG?=Y}%-2&%+wH9mCRF}70m900Ja`TAB;DX; z_bB0Cn~fMC2;YWVl9*8aoz%-)(R%5K69&m>5_s=r zTSxaalpPXE2-3lU0dxnCIX#-jD9S>L3faS*Mv~-h0b~-2L9V~{X-DxFmpE#%w9WH< zttLh?a=#F-v(t?sPR(s6KhPIH-76!%maHKjv+Y>pj}dSLjm(;=@foJ1G@4rNkSAmS zXKYuvu6~p*HeiNq;sXioSQ7ReJ#)#^s6V#C8_I(#_j`cH(FY3pnxt=)xHxbyhDGnh_UHf7@hR>pqsC15~iU1=Y3l$Z8zR=g^Npu|HP3WRxbHRNBtoF>M*RL57A|63KorOW-c)>K zzaxDUg+m4WxPykq6-knG)f*-CTHzsd)(f#yu`v}ir3lG}CSFM?58y9E^jGTu2^CEX ztJZ1dTbL?ZY}sopQ@lOwpX-Xn)(r5vcyUX_#F7R|5bzhY<)GfLE;*vzBo2^8Pl06z z0KzgpjzT2h;j8P3!*EC7;30V;4dO1+Kq^AII#A9u^NTzXYk&4^N%$c?L5($-*JkrT zc9fLO3NA|m|AL{uRup(bJrrfaXkj^XlwDw5QOwzFei`GTH1%kZQiPdRtps31j)-Sj zA?%%+UO4>2n7ey!PAK%=sv$UUG0@g1yJdW+P|M{m_{>GA${2#_4F=vi%a9VFGs+uA z3?c2S&W3=OF<+Ys7+94o5|wTh0i)9;uc2z!LFlilq}DGW$M00BLl9E6PT ziqMqduGg`B%I@Yp<2FD)1N<`W@SA|JtPZ3PL@csq!4lLhvUlnxt}TSbN6+DQv`D%$ z+4qZUh&5j~41poTPr#2v6(2DnJYai=o$y}ER%HlTmgV(9>$idXFw|VA)cpY>Hb1e$ z99V%S9Z1o!S7iiB{36zZ$!6%F%M;*zWP=QH~j!5`k4EDl>Ggxt8hvyhWbMeOPl z&_%uJs3e+)5>zM)u7ZpI64$Xg>w`(~+|SpSwdbG_u}?ymOHzeF5=Ex(75%MK%gx|p zpNEbtv7Sgdg&#y}>GQ%|L!N1cB;{*03TsE@W^V0FJ6o31wUXgZCE}$g>=PI7F`4UO zp)lL#VQ}O~n{b5`=G{2-FjfGSbQUT9A$Sv)9u$CWRTnF9NQwf7l(5Txi3!EK#}7Z^ zP=xQ)u_;1*<+Ay@Wz%-niref|GiYk9K0EgjpBg@0>$wU=r4cY;O3XBgeb}O1{qWDd zB9#Is-m$wZ?slVRPP>c|g2?99_AK9iOO}kadXS!i%JRQo(`Nyyz%?{qJC|7{+(c?E za&OU0Rm*-@bIh@PG;b(ef8DdF-7^&2UZ*-UnnPdC(Zc z>J5}UPxiDx*lqY{D~bg=;!{p`j)s8N!T{o^&*84}N~fvCyIO_PVZzCF~Q z@+^G>{qPcuJ}AP(K3JR=uKH#ZnMmhk*aYWp%B>BBm4~?&UaKkVr5>YbOE>xk)|%HL zn|J;D?G}6M59jn0vn`wU<*iKC`3dWdh7$h@^mFVr4a$G4Fe)VdBKu+~O&=C_1x^?rjrncRu3R6a6SeOH5V z{O6n;=;*du;A||GI#Y=B2 zPU}UxGD>=O_R`pCqZ-ie{VuX9qr3s3v1xar=zp$yD3|)J>24H{YG0<{c$*k61$+A? zWK9;^gH(@m$KD>AK4&N%&K?Sc5hIdt8v&i`GbOTl69bk$s>b?`CTHa6HdI71lP!V< zfB)hHP?lR`7Po~MTLEy66_1)Fnz28!J_{7vyL1z|2_aNG z)Yh9JPo#0|0b7y3PBfiTDa(pJ6>RQyt-%oDKgZg_|Gsi8*-IlrC{(CzExv3b!Sc>I zW`#-)3e3c^OxPC=RsWS&YWFQtQdyBUF%XoS!cbP# zSe2l5y;n8jVgjNbELSNj3%H|YE%xbqYYej38!!6+y*_C^mT2!npj#NjhD5&yJYH#0!x$lbWIz}(#%d8=fF z&x6ZM5D-t<;beo4#?8c!fwThv)BlrmsBx{-jtNGqO zzFn~QmJOwMU&jj?A5fx0YybN@`*Z%$O@gBhGgf({19KLuQA89}=CQ`OA5h5{eoi^Q zBTVe#M2fbzaMZ{9s>rBjSg*=~OykY@TMjuLz9iS!1fTt=QFy`^ zt~6On$eqn?wG2kaQCtT-yA!U$x&G!JFZew{J;Afb;!U^9i!P^_0nCi%WBVjVZ@$$H zw`uzd`^;sv5qUD+J7bCOGAPcU*zBzGcxm%$|ALl?mfFGqE!oz&uk^2rOS?A2|^JOB;2*NvI|XTo z4JussaFEu)O{Q_&-ULAlzLr@{X*y``V!aE7YA9`DPTlb6!6nQ!$vt!_tzKt1%U+Pw z$7gTU#vtJnN~v`UD2;WlD~$l)fXV6qu>0LNpqJr!6w0)swfmmkrC78LT^dIUsrkW}%$Z7c7F1yqr zW4uMNIHw^xvsb5)U9lLSx30<`ST!>1k;pOM1p9$!@6X4RHQ3?Flr;+LDI2W#(5ILf z!xNpy7GFHDcsh&6E*)E5Jkm7PpxDYiTdPY2g_u6_jp9h)p;bOz&|e?Yw(M9i{NbB}=83yZ zHm9RGQazk?9U-#(fQQ2K5{7kSqu`$X&^$B`)D-uoE6^2XX-CWQi1P_SSJCZKKsqF9 z+}jjaW{i+N@+@)tOxU2e9&w_0)J02>EqoB_|qz#DJ!b%Wwk+~K^;VLLH81NqS4V6@q0j1k-G-A#KU&Ld&M!<@s?1r^#l~c zR1tL5eCxpo$gRV+m$O_!yjAN|dvsvcACTHUH^eJRk1-pRFH~9{VY;bG_tBy(_VMIw zCDZ|Cbt}m|-FCt5d(4dOvZb(z3Mo7ibDE|Sz+h=iWJ=V;F@frf3IhMiTAj(?9_$}I zZqRNb*?J%{?g7D^hkl8pPW8MKS3ap-ro3@VElk3DVD$_esL(Ln_~`~&DLoJ_Dwwor zV&;T#h8rzQV$4x0(8&}cEnftw#t4UG4N3wT z&Iqg5otHLqJteY$U6gAsp!}nN3+1l6Xl-r(#dx8pOIlP4Yu9tsU}(L&DCcS9$1pw0 z%Tav7$@}hy|G>e=2>C4Ey!H3j-%KQki7OQkCr$PrSORz(dqE#yI>kq2co>(SYhyQS zbxJnEVn@iUQE34`lr<}d#0?2ej{n=Zzbw{}ZeB=b2kYdZ;zif>yB{-}MV#_k*IsTaz|WzYsqQ-c14i0=Ka#bTtGH9!Z338NbGU z*^bX?H5yALsBK{w2>#5_j*veS-E>YGzgK%1svUilZdVu{wm%%D@v*Y1;`U~#nZHMs> zAE+yP=VNF`!>-VmL2MUy2Y>la*Lkno{NQUd+`*srleSk0ucktD?ybA2ua|0X|?p?3z>R{p2;YN++am&lj%kJZV-WwD^ zlF%kAcqyP^717Zw5`{}Zl|Vo<`meCF*l2h!Dr^d-6wvs0+*HW z{!p?-(~Q!T=)0SnPLFRqc((q#wh_youRS$2csoVynn!QB@jxJ|$@(*+^Aa{9z#64r*hYCm{=<1%1o1trp&3$^9HoUhhoSzsuJf1Hs7VoQP zS7O}3hu#+~&cR`RAWn3hi?gwOY>X?~`ds`DH`iJAC+?kKd(H{2!o$j;J-JbDD8O@j zA|t`ob!<$`97x|gVaJgJ`1nuD%hQa_=45~GOKqI3;?x!o`m!r`_Vh2AsLx)GK5#!I zxkBdmG>PEi^cISzktA)Q{Jt6T1%%#Y7ajLto|35|=0l4Ft?N{$L4zmwiJx$XC>QAW z<7Q@w(9XSOS@P!nsSDfr>ZNBBG;7uCQUWi$7;B!6ie}Izb%%D7tmFh+EGqZolV-x< zNz~^jLY$IcDMNa5ZwUMij@{it$NpUXo?^fjj-_Ywt-pHKIW7(3q=5q%1nIwRcGDO2 zCqauBB%h~{2pi{`)KRevDbS$Q@OKO$Q!(nmB=B5KDm?GpFZ+~VI^{kNF%=GgOW$9% z^-W*~Rb^}B8B~6>~hEbgGT8dRr#v~)UTx~A-#8hNjrOa(U{1| zRq>owKP;^;{;{>|zW>pr_^I{vh^!v^=egAFeuW#=a1zUnbz~)t)Gi7q%}d?#;01uZ z;hvM}FbM2d{{qk99>@iVP>TG6a?H`yB?m@sqT$U__XHKnxJ;&WKKD&Q%lLjeaHf2n zW@f@sPSGznoby4vS99z_tv82%n(JrmqXXd8!{Z z^_N2m=WR9hh?*+62Keu;zI$~E+`8GkquCGA_$qZC<<8=SvQblbqr&o~4#n+Azn7x^ zNNWs``iy5lagR}LWDL^d@3gq0ky!Z6gUGRuBzmJQC%q7+lf$Qc6^2XXM)KnTyPed zPq>8@oy+OA>ZXiNM)1xJkRczaM~N2d-N7?g0V(;4Xa%e-k-saQ!9fXt2s|v9eMAVP z%XIdA-}=&_*Kiv61tJ=RaI2)YSF_nz2N=;e22sN=jAG{h3ch(dV&QnXK8gN);4A~V zjf%2#hXQtJV5#=%`VMYv@#pkBe*T@+>{?TEOZhN*Bx(Q5vFAa&#{WJ~@9ujax}3j# z1uvK5-^@cq^TKW>dEmC7(i0bM=2bXHJ{&Rt#nu;BY1nfxtX7|G9V~Armc;s~HE%(5 z=HV4b81wFGv7tmqvi)}a_UiG5a&W3VJ&8aWZOi$AAly8!+#m`$r`nFi15d3I-{+IO zVVE7}m8#1%c|FT~zC<{vc~Wz^4vUq= zKi{`$A^-Y02@}O9$({GwKzl747;nI}Zvg**6 zzqkCnk}gz+p-J;xpnk;axYAAgD&EgE;J4J}w(a?TsohQ%51u|hJld}L)Ye|utvjPT z)U+Z&8jSC*pM~APC#uJIp25dskG9{(9B`SorjLZ?sl>JyEkAN~htoQM?3Rivz-K8u zW#MHhr)3~1Q$Q-SM-eSg9;r^0yDSW1ss%SCCMVlcP{EOQ4ODQGJ`TEAeRXe|eQyL$ zI>ws;x7hbD`ov~^ajLG>@u&?}Mu@t_+(O(|&UvH&vIFfP5$lQyqQxFEzXdG0vNKem zJESwJ*}qQxC|L}+)Rkt!puz%}#F`V8H+x3;>14#VvA|iZ3HRFz@0}Ydqq(JJutiGu zV0>l18`qxAUq0D%nkWTgo?g=tv)-a8pgb>URr@@qN!82MvKv<;3Dm#dHf5*5;d(x1 zE3nn($kVW7%J>;+W?PdDNW7y8x}#!>Hkxnn_{a8lSxvEC8csPSU}W>tWE&t)+eBKl zTGl!iOAIlClhOjH;FGZ;@HgT}yST1Ofa(Pr*hN!Tnu%&=za94;uBNbB`POt$WwQ>+ zNpvTJ3VPszB-~B(6`Kg{BowuZ25W*wfZh$ot-EDJklR9qHdwn3hh6n|4*o~p2?JF1 zg$uZA5ikVMf}YLTm#E&qJAyvLRp<|H470nGsJ7z>vYU6r8r|&wrC(B2+|HD_)5;~n|uAd zd`P6^YmJ0Foyc;*VuAz-iHI0Dcsc+lfe{Z3o8Cc)q?bMz{171##rK*D5C*-^3h?fX z4!Ei|m3+QI?~ySCR(rHD@vVZeSNBhOMpOGp-+Oed`mBOExnjdeSzCAyy7{jMH@uK{ z-Tl-l6+b8(h(X`o@|I;b{h-C@r*BGZ?myWlK;sHEUa!g_=Z2U<-J~ubcULcLQOHgx zLJ&1r-{wj;N*CqESk}7y@lj{6G6;H#3bet$n#?sjGJJ=r_5Ln1)9J$t5StPJf7N2+ zZ7L`ZV;dSy&TIfWuES6{=;W+p}QFguZfqWN)3_*F z8|Gx@!PXTQZUX9b3%l8i8!Qd?T3JRC!fV@_qJkF^=>pI$@>-$4(kqi$(}R6{J3O(M zOiuO9{-ZY=KK-3RXd;GhN%_#0#S{xKm+m<-F|aUnpKGp8R1p!XECDf~gm;;V(Vq!i zJ}_B0VY_u$3i9{)%E4FR(_ea<*WSLjRPkoTBYVj>xmHiEMv&b;B?<+{{K|LB64AEz z+jk51aKJNeVcA@hS>k_GcGf|0b!*l~g1ft0@Zj$55L|-0I|PEeyEg9b?h@SH9fAgT z{m9%qle|;+d*|NMb*j!^zrFUerMgb%=C{L4aqA<2 zsTX{^+n##>P;7AXd0iX@?Z3S~*WrPn)n*r@P`tGZG3gg}okL_UNpEf0Zm2*vV2;hF z%ZLVc>T!{!&J0OZ#Z}3KC4|hub*ZX7@xAT>E9?HV_P*z>^S0 z8T%h$)GLa!AbxW|PT+Sy_TY3tK3o4%-0=cECSl2kY_{0v`5iL&rD)03(S4;yIxqY^ zHZPS?@chagfs%gT)oDi2cw|EPogR(G!obODvMWk~5+bh)FHZX^z z^AC55pk?3I_19eU=`w0h6O7f-$x*t%4cLDxGpKG<>?$_G+xe;r_RZu4Ab*Z}ZvO(%e0$YABd*{Z!&KYt zm=iYWDfRWZQ?JI^T~*2c)O^wV6Qo;0Y7FQ8>w<)VPQ_`5JLp~IM5_xZ?DEO#xs$hQ zu4+jfB7CaWd~EL>@Hw|Ie|Btyp*q4DWtRLBdKOiY?4AVuBWlA6aiY_WHZhdbq3Pa~ zm9m)2I#EKIA1QqlAnt+cny;)I5T+}s_=S(c3Rq0GjuVa!ZkIP{?w$WJR7bCtP zeHZDT@9-?B10y&&7iO!c>RZ&C#-S+I8NvNTVfVdICa6}i8~dGTj48$?ig%pQtLPWi zzyt914`TzzVGl|J3%&jgHO-V7_#jVdoY;C*1ZWZBLKT_!#aetJ;lIkKJo;hSGB?ex z77zSpV2Nyfs9kBteCC$9jt%6@A+kb5pAXd1%-_J$t69(4|0eYACMxuz;lV0!m1tUT zmZ+|I|CnQKfw4dNAk!}SLfnp?1Xg&fx8YEUpkAgBbm;7AV_2xctkft>#tE~7qBhF> zdbIM3+~Bwv`1FO}=EpKHJ86J8&ecK;_~iB|?@Mu3*pQhJx@jH?^^+6po5v3ZM(L## zPBvIO3~0NRQT%gFCJ2x+=-V|DGR>}4XK5eovmRuAxCL%tPqt416HTMQt?0+AI#X(t zvGnx?)n^UjI=m%`ET?MAWfqoIy@bz(vm7ko=T{S?egc|n2oB)Go8qtj7|n)+F`oZb z$6QEtD{v&hQBT^%7nQz@Ef+w*2fJI>+_nUa<&yRHW6gHp&S9Vv+Yhre;d~vn@woc( zNcLAnAd&Z>c$jbpvFLzQzp8EnPizfeaEOGS^KOBQO3ARKAfyTs&>#dlrU+(^TPc*@ z&q|ETHR=E;HYLqOOG@#Bg5XY~v|*tm+NhxRMiaOo*vZ+IOHUdc?R+o$H1rgQu z8b8X!I2a%0cK4Hn<#LzDTS2I%agW-$(kJltEEB2+na|owm*}ZPF0kOVhd)z%T7q|m zI6Gx2t{apPCXWtXbjoAUAI3(e3Zp8;5E~}0aj7Hsz79(0zvc!39p-n6`3(%WSe$Ej zOvIe^`LpvK+^=+-BLm3e5s5+M zBcaC;1~=UO8U3rZe`B!5OeI@qIQoNbt#aUu&Q(;wJks1*d6u_QQ|j)_2wO740v{cB7!L6>w@UYovJ3gzTH_`g2rw(=jgr27q(J+c*Z)RAf^(pv85CF`l7s015 z!6&F98mZpy>4F=j`PpGRWj4;2)w~&=}Y!vvRUp9IP*dsPN1U!LfN=G$QU2G@^7(4V1B~ z>l&7B_gN^Um#gaG;iN#g9!20JFw&wkd2hl#4ErNKJ8h1$CU^YbBamoV8W^Bb(h5Y` zzu9w}+BclefF!AQTQJjpHZLy$!;_qzy1ttlm;-!E2lHRrmd#xQ61QQwkP7-B%7RH$ zKcAb&FV6)jVR96YaV~B>i-z;1({MX{L1Eh%_>2qRami?PbTl-zGgF3lFKNFD$P`U2 zi)HE+jd#GB7&PBgEJiBILF_)SI!0A2lv+sE`TK}A!Z6Zw7DmkXxu}(%$Ts%*KB&|F z-hj8JC*j0fc!m%W87LR+-t!dqbxb|u6MVOz%*rqr{71+S-5n)!yqGV%sq)Sf&$|H? z$U_x+*_@1a3tBo=O)t&$&`IU3M)7!|eQUU5P^pfbm!kdpjRv z9;&`X@Fmeg_9-o9>Ii;r%{m5-Rz94xu1+WW-spPKLkM9mN9C^6ewy;>0$jbrlJi7wcj|l2&(u;-L1Pdp~g1Sz*8L*8+~4 z0^NKrq7nIzi99&3hye6j@868<(S?PnnF%E;vFGJdnjExf*%KmHYPUpd^^Z6O-KJ-H z9U)Mw+)pQFO<(Z9_iN#N_6I>KNi5jVKixNQ3s^Vgif36+JaF`3C3#_u(G@;W;zyL- zhYy^{t~Lb3>h2Jy1RhVCM7>q*^KoB>udp!We9eF4^8IdA0ako#SoC^nJs6!vjSfv( z92K~TC%vy=_XQ3UsxI)-EI}G`nNihuea!`AMGg)9^(VZx>H20~%pH@t3$tl&DqviX zD6-fl|KL7p==$>Tu~%1!!jV#7^qzu^{|W6}cD<*B(G9m*Fbsz;=40*`>iSJQ_8!0y ziG`$u9!16yEe9y7bi*RkodY#RwDwyZ?=V9eK6jCSZs#$%R^+NC$dLBqSe*H$(~Zns z#_if@rH;r;Xn>v}pC=|9+8ey<$8X5kp_e9AZiB*3_Bj}eUlr_0yvb7+h|#GvL*o^i zk+ER$r8f6-b;<0He9-YzXZQ2$ zS{W%7MGz2nx=e~*CwuY&%KAr!ZVUsRjZYDnnOtGtz(WZzX9M+UX~rqcB~(5iKg=b> z1eJz{s;K&F3L06-&Og{Q<8|~+n;vmeTlJZG2+`!4p<}0CC`q;g2YL23c4lG4KVEu&J(&H;pbjmfwb7f38irdNQ?hr;aU%VQ{2dc5`z3GVuDwy>G^w zk?m4Sg-|VrPEet)mz4zr^dz2Sl$82EV|E6sazw0^d~)eoPt^8&*^T1_8C&(fU%BkSIqQB;kMw{YGwF9ZWH`K6x4m~p&j&UIL*-mr^sbV< z%bnfb9CB6LmivZLmOWx%>J`RLnlU`G_R^tQQ*A^2HeJ4;k>}n!)q^Qr(&Z$CsnENZ zz74x8W?#D&$hDEdMjwEJu~nR4&36*g2X?J!C=}His%4?e4|Q%$KT+Tf^=A9tUj)V1 zC>gXSkX+eg=e}8^g$%XhqnELx8fpda8xyHw?zdfPtiF2(sEB16XV-L{#24YTb1-M$C*Dd zGxVf050!FGQA&YvmA}PYqGs=oL#~K6h3oMJ9?JGm1{fmDV+Jk$yoPJO;46ba%7w{+ z2C{B03RY4a$_55mIn;hvM08XieCoU~9Ck@Jb@|5-yYK`2r3&Ro+pLu~Mdt$k!gSQ} zSzvWyD;Hn;e)5WYTHRRUJSHYS$4dPqBWF2nSu?Q~%1*SG18~ylLAUH|nt3Q$X!jB3 zvIPWB&8v`H(eA*UkpUd#Ds`C)`BU8?F$&E-gY&zNl#w_3#?Bsh5o`09jcN*-6$5p9 z;8IlEzA+pR4zaD$Z9V#{xfWNOqPCb;ExZ<(; zCO1&0;9=Cp=qa6jHn9b^gILq1xxq62wkBw7t~m~ki74Ki`NfDvu>t}ylaRRLQN!jW z@o;HGbK|O6GeR*|3lvy^AZ+fjfvfxuRv9QTR+wB9XRzIV1y)~jlxB2P;hVgckH!XD zy-a6(k#_R9^NIztS^TZD$j0)5W!qm!j(G_l9~s-w%RX?AfbeN|a8r*p0Bv*NyV$;4 zL`d)9SLXq_(N*K6n^>HFY>_ww{HV|!$`|!WnV=KM*3@1ej>lX_Vk8XgX)tBj%Hnqu z?Xpx%@wU?1{!nCYgrZ@LAU}6H(fyQcmlI8xcNz-nl&>qWEgAFTNRy%-MV-Hhtj2*S z$JqJG3_DbW2(cv!Zf&7bM*<<45`sHlHgVJYC_FBzXyt^UB}i3Cck=UnRgd`(%jpTLgdf}{p2ng& z2m(Zbym9eD=a!g?bo~*rvxso`DVhA=_@yG61-&gB*XNQzJTxb1vlcT`RCu|-P&|db z@JPV6?Tj;D)yf;HDqwKj*-Mt2EQ=>;;Fr_L4}gN3J6a#f>9w_ZxX)Nf>=D;3HXHaz zZuKW@*(2HFxe+&*f1gBNJ)qUbM?gm$seY9J|Zc#SMT8XmYduizo*vz)gzY-EJs237CV?y$H! z3a({vGVZBIS%z5G^*1kN#v4ueykP2#MKe&= zrAajh;m-^PfX_75lzKo|`f)_gp$)$p*NQ(<Rjuog5(Smk~Rsg71jv8DuuFc>WDfL`2K{5Tb@X0LJSsw z-|sbY=ExeGr@g8nUTvgB4Is+vEs!UA_gXd;k*9=__1z_foyhTo?}ZjR5mSg&trjY` z3e#e8U?KV*25FNP?nxn$YQQPx>^jv_$7-;{?9i5uD@AQ5+SA3?*hushcE7klW|FT2 zKhZo}8;Trn4b7@v{KZx>cdo}#JwLyDUeL_+ymt1at%R8rpoM5QbgH37CcXq$?~HpP z0h%sQ(-lMl<*a`B^t@0qJ?ktG707rI$OM2u0i0&hT+yQOAjePRjx7anvkqHSDQ?J} z7|U_>Ar+~p6!NfbNFU%U%*>P!Nkm&_h7Bockva^Y%i@}ZGPHG& ziXrN)qXeZPZI%ailjy{(1Hqa0#JU*mep`C>Hxa_*&!vGZdi!i{yl)=k^qLj=1eTxc z>r2%IkE6Dzt@iiDw-!c*Y>Y8Kedy_g3Hdfn*4RiEun~_TyF`u=pZy z??O*989?1#-sYfDXJ6iL)5ehet=9vyCwY8DPkq@c{Gog8inuWK@)e*c?W+1(F2RA5 z?Bx$j2LsqTbiNPFAn4%x1}3_go{~6m9paPUILf6^+SFEQol5Wlh=fJYuy5S^Mud8) z7LaMYARDbUC>m$3BEP8;|>GE+UJd$;00O*j9|oPAmL^N_cpP_ zGozRMbTAXo+gU5Ml4enZ+bUWo_3I4^jdYUsu7FwG^z`-#3>ipz-z+MVxK@)|EU+ro z`W0O3Y##4Rwy+3$DD4MPwZ71Zd7&lI3{=F@SSojd%qI*|8sd_?;5YDypKv_F23{o# zrmJpu7S|(?IQFPXXBM4($siSm5cP^%8+v@-=Y{$@+4H;Fc8Og@KD>hB!_h#J=+i&0 zT7AOA<>Mao0cKlTe?uOTs~|tudOtR3>l7-0V1#6tT^V)LrW7a)mKlk5aj`q_ifO7y zL02i$oZj9IlWmk#edoZy=j(N)g%Qpv?Fet3-6$XbIr)HU zQbdAK3EHnIb%SQ$s|OL=r%9~TcdIH<_%;RaEWi-7`0CA(X5?7OPav|@^=%Ha4x2|* zkki58SXX^f9W3tk_)508q%OX8Y9`=9A>JLaMvxh>4Ru|BC*@_K03h8BKiAVc_vq>myRmnO=_(C3LCwiD^v!M0>Kv8pz~b z2B5Q3%juCTnIxzXXDT?=ub{%~&pw3y_aX+HhDG+fvP2`a~$gb1nQNP6_ zld0X&uN%H&=GY8&sOec#ht>UAZgW3HuURcS%8zuK-)P-RC#bH6e)*cDKQ;*L>q zz1!_%stIwu6V0q$Gx%mk#!xv{&)s7c2xpH$r{XYO!Tb|5PYj*dJjJ65_(v7NU;7Ab zf|0MzWJ+_LKzn%$4Ld^@D}#nd{HsOH>t6j_26**M-ZXR{uW)SYxcJ0Es+#!#wL|d= zeELxpM0A$rV>*efIs5BXLEYQ3oSvTvfg@gO1P8{ z15(=0tKIWnuN++W;*nb~I&LBr2J+A5K@8QwPM9c>c|`^n3d64;=X&C5pN!O^*lf;J z&4jBhV7H3|J=qs1wsowQCo zVi6WOW&-)flFRiMw$6sij~6M}OX9=5l))-7^A(Ty_t?gmb8elz1Wd3pyDby(SHVHA zG7B++lrf{pPNEnK1u4ie0M)o(ig4kR3$3F+p4Im6WniUMDp?HUOM;_04CZo?$hcpV z3OeX$*&25#o$@0xu!{&Do%)6ue7%wgX_qZAI6Jq9Rd(=)|kISQ_&HwsEggKITjDCWiaFl*v zb}zcqJe$yS67D5c!ip;9_FqRE*6$uyi)ftrdMFs4}Zox1{E@C}vqLuwnUR87? z+(v&2Mmq;EDmx<67KfL6%vn2UmYZFh2Mb`{=}HtLm(|RWX4gp1*oY5MzM`I$0S|!> zs?Q~reI)Xc6t686u*r|2-x*-NpsIsFcMXp;ZYGWRNNt|KqTmjVxq6wWb6MiCU!Ff1(wjbsfOqasSvqn%=h6;B zlJ7jJN28CIW@Dpr{J@ev%RuEf#@fduFMrk?fcsToj66Mu(5Yz|;e$ViyaRS4TIfMw@Vyqb;phV>!45QG%{* zwS4Qdn?I9tX3d-MgHMum@6h!Hjf*?@#3Wt?!!v-+$Zybd9-VbK)zp@yuOp+)i$T*s z;<1dDJ5%mzDqM2L<;#T$|6DNN5p=A!m{Qk7OV904s6d|A9Evq3UT{K5MOF%<+W2$1 z7%=_zCy@IuE8J?6#UA%1)Q@rMIBLke<_vw&V=>?6(Dop9X5WLgzxcWHoDL$f2M)epm<7c)M!8Wquw6=?H`UcQ=8m)oXBjn$Y$+tF;2-+E4^yAo*Z6AFzs{Av?c;OKJuRD=9DCF|Bdx^0nmY$YT}5 zjmGf4o!%gL@p!%L2EB>H1TJ3J!+29QDAv5@ZFm8eArL-$S`zNPI1OtWI39keglZfK z(9x7Gyt&RzI-YLmT2EJJyU{lE;eLj}HRWj@m%F-q2%2T=ovrDZt*LweOJ4kgvU#&& z36{dJP%3hv1fHfuKv>==%V$00Q{@#U6=#hW=Na9If*MlARv<+UJ4)JWCECLHB)Oyc z&{d_&GmJdzVQL+COQ|&4OQRqAi$d-!xr&99c{vdBQk9?Ucnf8H3(b!TBu@+4+IJUP zjSjM0JfTn6?2O|j4cH_kYa0(;Gw266aFx4J&$SYSC`0s6q$6iJJgZpjRjli4VBv^d zYwB=8l$jCLtOE(ZJ*dO`m4ZYMx%Y0te5&)V0P;a2VbJzcn7wWAFp}+Ny}D3dMsQ~WGpkp4Czl&usRrxRA!JP6;wzLDTywU zD#jg)s8AV{6624OKW5RRZLp3>Gtd(QsIV-?QhMWWW=D%l$I-^*CFS^LvlvUoIA~d~ zuGOc{7)$p;oKq=j(O4#=XD6=bt}-(+jfpk9R0`7%-&RK#9%iF=_*B0?W-5*nalB}b zizV$$nafx@o)@cX$=ZEz{{GS9DTMy?f(IbSld*1R$lmSxvS)7jV-^Hr_}p71f1tE4 zX#~e_BWXuRwD!*SgV+RL^K#PF@sy!4a`3?>7`NY{r&+A4c|Rg_wow?$OuSV*5nh`@ z9f_CO`~`GwdtJG6Eg>(qevpVKu_^Yz&=IPA#-0V|tV&bK%`CnZJI3%=!%#IP`Q1@S zycA_QnK^adKCW;bh>#XC&~N7UnH4HE)c63oC-b4l9cBWp@d4M)l)Z6>$WN$x*74UD z^my*i0|*=KxR{W|$1Za5>h)vgBrYHM%hH&?n)I&(GrzjFcdCM&Me;rougzv}eM!2G0^iQq?>+fN|pU zsf6+r0{RNV=o+KKyer8y=nH(S@tNF~Qg$f&34#6Bv)1XCCQyiEK=h@o=K6 zFzh_89O~uSmNY(0Ggk>j6$-Xn6J{M6$qJ)!=kpR>Zb}FAP&LJw68pM3m!=;vx!I+N zSC>v_B9gs{mhKR7MK3P=NO?TfRN2%Tx1;EjOJlM*?AqPl!VAH~c%XoWL!I;ZmB0bE zhxnZlWiMQAEII@pOl+TtIUTZLo60kc!6k;9jE$OCIu<<4xEYvwog^mK%|GYi^a{P7 z!=Z*!-8`nC;I1yXV)%ll_M>W3KSUWkG}pcO`4F&BC{NH3F|TCIgXen)xpt|dH9vR} zk^+^9pa7s3U|Sn*2Uf(3`6`>R1r1C~>Pm#5I(B}qht7sljhg`U4VnD9$uM?vWdYv| z7AIwt{1})@9_O2${Y?+4^e6Q5y{=IkyXYEg;`_%es_$1V1hd}=xl`D8sU(K7Nrj05 zfv!Z|8A%vA)dz-AjI4Hh`b-bi*f0@-LA_os`tr%glC{El&yeQ7!~X94 zBvjw^%X^O0uluiJ)7~5Ujpg`{#BLz#eeHn)df$VAfN=gP_B}n|UF=TppHxd56C2w1 za5*bIM8^sm`%fA+lUUr>L0E&Y4+ zzs7X@Nhg8(qXhrd{4YW~{;rvSU1`+6R9X??k7oXo_3(G(-{tvh(!-w}$o~J3|Gg6Z zYwf@H(O<*bL;i>M-^N-0p76igX8kD~j^bZn|8Lb`@7n_q5X$=}@BQh;;@7hKf58wv Ap8x;= diff --git a/packages/extension/build/firefox-react-scanner-extension-v1.0.0.zip b/packages/extension/build/firefox-react-scanner-extension-v1.0.0.zip deleted file mode 100644 index d21982244be9b8abdb39f9dbf80a96ed02563e25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94959 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Ω`_XC_nx>l=mj~0~;Ii09_g=Z3Wx|SK*}KC!{Ba=$ z>q>6d`0@p2S>hXZX)@wN3#y7Z15wNbs|r_%=fVCYzKyRCwQ_QV|7XNsO8wJ@pgCK$ z>&E~*8N@plh$H?yP$ErgPl8bHkjtt^zRL9EH5w;5sCHSzb_N~@JYSfk=dUllTPt@- z@r!2YXeLcANlZ`ddMD2hJ^2=D@~&!uVz7X|L*JrvPRqj2qG)@#$}@U_feW-T-3S0* zl&9?Ea_EMdu)M}_hk8a4^^jEIWXC}*rO!k^T%abuzn z`-oBxERT_HcCf=ARawT7;?uo8|IYb`>HU=wP_(8W?;bbK>V{UeeC6Kua+cS__#eDM z-sxocWWE_gW@c(VT4z}M-+qBJoatolC`(XxRgxKT{`v5naUn5&xvt!IF_5tD6m9w| z7jgH1rUNA<2z{jD8bsvlKd!A?8ap29vDdHPllcs)oOAfGi}9jyY4A$4ERo46Ae4uE zLIOO4=8QsDHd<1wuUe0J>E)yV%{!oNk7t#PWkp`|@6W+PuDBv$`tSI^Q%6cQ@9MJQ0 zp)n7~N%Zk6>~os|gR~`Uk5J4KMcc8(Y=GW7{1(UlfA+OF?o)!;JlO&+!*QY)*teSPNUjjFBIjg}JhDFs~R8YzP5+rQlL#6Mp?9di|C>NPI=* zi?>y%oJHh%wSr=wU>%&x5A`CaNKEc}NOpGV9*gr&ximi@A)i`ro(0Y3huCoyI_U}i zHRRlcv?9K4JT^Z?!EtOe%jJlDt>319C4;9;bzI29fW&12pF?8sB>?noSIQhHV?zb{}BdE|<9Z`rdv} z2rQd)N|T^0jMdY{>Rwe5BT&#J3fqay;K=svX9C{pc8%Nxui2Ei7Ku)1|MYFKrCqf9 zc7ncjPy6c8J&j=Y*js6W5=WDz3tn#sW^!i4U$qqvZX(EOw&UO3e z>$So3<04)3s@Kepg4G?Ou@Y_GXQqQH(`XQmxjZ_4y@O|K-d}G4UlX^_&%gKt6O!*H z=cT{Tu(UA6j)o-jHpQK(MNH%7Lz@MS$t#4Y^=-+!$*Y-HK7tcn@6ao?4e3*{re*b{ zsgKkAwh!kl67B8|f9lOA8{!oO6oCoW zH|j_?_}juy_kJM*>0)~)h{EC}BAcT5>UifPVOf8 zrLO!t?`$}lmNXxAa=v%q15RI05FM<0b!Z`pgD}eIUkgKbcvWPiuJbP z%w9=F3cc02sJgQz@~GDfee0ShfKUY^><{ET#0$?1+TOI#Rio63^2^lvIpJWm$g#PW zw>L$dinQx#SORw12?vo12}RjSJ@Q;AZOB3d{ZX}{p|LvZC53+AgCbo_Xtv3*iLAxQ zLMnT(pC;x;2;V_h!vef-L5?^N8nm*B(nFdHk>0T*4N0|)bybExY$FM#+K%-EJE^Ac zaebe;${!B=9?{N=(M^#&m}z@!0gg*5D8<}?J&XX0&E8eVHh;%?QH@MJj8&Csb=h|D zXY;!y8f~;%+1yIXhspKFmj{2t%=Lmh$SCQMjW{TJi(1M2+6~JxFsbuET|&l$ZtMi5PQJPym*pC)~i zLLRVzw7}-58l&1z2CRR<%QHVK~ zznPDnmut3O^a|`6>)vCyZB6RTg|1FlBzUdVh@!%?AGbi4u8l-I3qLA9w8+w^dUOi|06y z6L?}e^ih+zFl3?_r;p+FWL%pl^l%=#uJHQ+ok5;(Qoucp6?Uv)a!gJ52M*$k7XJLy zOt}H4i3pvNI zuzz00@780EC?joV)?d?{Syf(O6J&uH^PsC#r0l^41Dxctji_D(Ex45Y6UHGCjp}j- zdyScwnvU2EtT$~|0dW!_FY#4%qKoPO-!M=w~cn3X*k=_@E#7X|B!^njM;;QWX}N(~h@^iMnm49)CX%G$a9v80%xCubU>88(b|lll{kh~QaK1j03i6W2MsP~*6h zZi#24@)4*fp_mHW&=OkWef1e zq7dQQxc$)Fenim-MId*%ghlM)oZUL7UaCnIT=^B%TzHcKIKaf951OA;xEN0i4OY(M zfny!*JXaU<2Sf9s$7>9Z+EVk!+7VmSlEh+e4`1<#h*~9_J`~vZ9LZ@j@CC~fLsG=@ON|26-(~y63eto>>?eBsDF^41sM#c2W zO`>19j?Krzm(J0tU)^*)_S!ms4Q!ME@UtP3nud^bUMfH{e&COFY50DcTxRRWpVeWQ znqM%tl$UXmk{dtD#M7(0jB8B9hNX#CTjQJ5X;KALM${9&WL7Rm6&q15rD(>389pbR zcOs(fB8Sr}(UFDp=S{xw=aSooNJ)N80e{>la{Giyzz@CQE6c&2BL+;Gzs4At_hz`t ztg##tw4rp{C9jw=Tk(iq2hg35an*kN5!-Zm2Iub1l)B-HVK9UF9H#?7 zyqVeU;&64~ZrI>?)p{TPRjFw;WA1;bMnu(Czk(NgNaMaxNp;X3XU4V|@#Q7=8x1>7 z!y`_Dvba>}HXG*_{Lg~lT{>%?PfFs%b^=shn3D4S)KqsJzce|J?@l-SRBFp2*$J%e{)`Nd z#AD?QyU@z%&(fs??YU;ffVLfc$kZ5eZX7D1lf?d9qeN|eCBbhG2o7~{GA z0A`=f?q>tKnn;YApw?Kiu%@z_QzMTxn@Z^VjV>~ zgV~{=u6<^v+9l(k2u5XTAEL}`ll$5H7=_U$aCmt6fbpkb$Q1#1d3k5Nc-R<3X;@YN zv~HB_{vQB5K*PTh&5CR7H&%_jcNruiEJ(o^**1nJ9j_-%Bg`SkBwv3mQ2l5wtau_< zP`CR=;gGKp5f%XunainCF5zK6Lcnu@nb@s}sakl<+MabZ9t=2-3OG71u%-leg}N?I zh46i+SQnA7HCtTPfS3|j4O;9VYubA&xQu_RC~Zc0{rw~(MKhUE+mok-Nego)RkihF zb1D#jXD7?z^`G*V!xRz`w@CO-Z}hOBv)&<-2(^8GWWO*ku>X<3U1|xHP&oNgGBS-S zPNey-%IEgnvEc|?wZ7WDb4)-#8oJxPi_hw_3(qFjR$3>hlOfHPP8?UVQxfWSp{vA= zk92;^>lB}$G`;`rMU}BUk~B&!*n)s(dB}!2H_)JprRp&f=6RWXvMl6}qdKc$#_BVR zLDMCGm*#AD9&Llhf#SsX!QIHw=9}*DeOf{}hph&^`*oC0CI`x^xJKV{T6aDzO{DkW zXy3SH+fnvxX+xJ*p`g_Ue5lRuU6LJ1)9&)&QD&aR;X6P4qe(b-A4|6!i^faFU-`%% z94_kU0;S)}9c_q}Bj7QDb$E!QzB~3@_s^=l?}A7X*t7wiUhn0+g_2yYg3l>kane`tu?GWF%XuOZi?{-VSb!A2(`YCI(wAa~*0k znYs4V+-ux$)G5g|j*uT0!`^-0a&-?~mDjlN91%V{X|J87`y<)5z=7 zP*8G5jxjOdo|YHTeLNd^Zd~-XrL|b2IzJ7K!FT0w;kLx;wX}Dz(iazDL_!=(;vmV( zfNHivpf`o$>3@&aX$j23J{|VV^bU4*48-8$3Y9jjBd}+-tKO-~>U(Z}dkrj^Kk^za zKIN(D>v0qISDK-Zykg)l-$^ih7uOY8n^5MKy)?6=jSwW}C zGG`jxcU3_7MiE5gJ*S{^upR4@OU2b+T~t^4*!)8Al9ln)9jq3 zIPA0$*hJ7r!SE$h@C%a~twepK&!fPKv`x1Ly7K%?MNPv_mgYXz=a(mF=x34}`-*vG zvm|i4PWQA8wa`-c?YUuAD-aunSo;jE;4 z>8>QWp^CEv4trg=te-$x?0J@wUgpGD#*(Tz z{@{n}rrtJ}FIQ18MbJvvLny~9=Apw`bhd<4@``xC_XBc11~%f9_y|euUD)Q^6iHyY zy0?>HPDd*6ei@O;W${e%yB?%Fuf2#D8?KPiUZLDcz;}1n6n=U7GkzER)JbwZ>&e7? zyij_)wD1qlwqEt1NiXY!$IO9GLV46yCyRRj%Agtx4;cg6sohvmRs?6OCW+)(0D3!A zr&eeN?9uBV=a)0IT9CLa(HJ?-?TlO!JRrz&SqXCcUKU}|?zU15!@8B8teq*1$NoFX zwwb6u9KqyqjkQpxH$c?UdzKdK`BtQi*JvZBWDSJ;&8!^?O0d+c!|?i*v-Ixz<}gz5 zd7kub{af=RhHPvp8@6&4+ZU-6*c*S#YVNrs?J-}bAj{`mHNl8`x;#0;2O?&R!HyOk zcb1$KtJT2QW2L_WnDkms{95rt2ImsORVv~=^?#m1A9Kh*NA>QAS$?6a;0+sD>~kEC z5ehp=f($tp=P2KEh?19zo4$>QyQ3HWC>zTHGI-A`>s~#=yhYs%(`oFZ(o<$r-Vw+r zb(*e`+Vk~Ajlq>36Oga{k>(hUv%>UO1Zjc#$dVGSpKsaiflmEzrl^8P9&T_X@s*c9 zs6cJ{zOOMipl8nK_Rv+>U`nn12A3A$$g)Yd2uUT{4D z)R^K2LxUNcQrX2a_DnaW(%YVItreWM#Es-*|031U2=0!cC3xzc(*=1- zg_?M71H(4*?kAHQP1xdb#b2j-TiFGnWcI@`%ZSD~*}{Hn&AYxF-L;k+WqZvsPIt}x zI1yFhtNSjHej{UFFy7kfRWB!M?0XgDlAL-O$+n;YDPN2#@>k@W)N^X)uyCiGdt*Y@ z>S8wqR`b7Ya}A4OF=-QF6Es)~j)poQU84D1dy1Tnrjx(ar9v;oSjBhwx4cmxVclrc z`}yy0Z?ZFm6N1xmL(wU>-FR(`qW6`I)xv|jrp>QtaiT+$N|MMOXG1)T(Nf2A^rz;I zXw+~g>v40^RLqn=S%;uEy?|ScewJm_r($&HwfMdR{Obr%_{S6s`V~ z8(BN&Xg{G;_SKtqk-yG$J;a!X<1&e4tFPq;uI_{ygV07r7FT+7K-+z9{o#0%BgO!W z@Ee+dfGeJCG`azY2N>gg+PSYvo3XyENLvCI85i5$&FZ^qv!9eZ6DH4zrpqLW*#mTj zl=37OcixKTGyw&lM9-Z<qCi1A#KlemP>}C@EW(n z@bACNhYJVOz>?h~uk|+?{^&w;+GSvdJ>e!2eO#xU++1I0f&^*P{hwA@u0Q|8M{FBs z?EyzqSxVN;)jWiNhQ^9B#S5=pKuV=NPM!6xB9n1kiaVc!T|7D>?WPnO9cM6r>8b(k z5|~F`#t}TK58VHR5+lrLSR%~uX4i+jODL#0F6HZOR34TR$k!Xza9C{Owm-Sf^F%iZ zSJ){^&d~k)o(ru6X)k=($ZuH5o<^N1nK~V1i&VALsF+iG>qThOhZR|0((M*Xdd)*e zneoddr#uiYiV0Bxt=x--ExW+5HJmeeCkiHz{VFC!R2U&3btyh3X8L*?1dsU z?t9H!F;*LCiDio1SU4ah2CHha!in9VN8MPlmWAJr5(Xy>WQdPnCoY_GB-;%%Zs4pl zxae2$j~eB~SJ60}^Z2Em9kd(S`KpbRA(v3tDIvk*cNjYcjB@0#9M$+))cI)>vUJNg?9^7VgG_s3fT=`YP{7 z3Ddz(ib4-qOSWH*|CKk+{4R4UkTd$cD10?3z||}xG&I1S+F<7*mg)=9v|#lKEh(h) zNI%-vNS1({o>}HIZnb6Dj2z%1YW>S7_rf?jp$w^UQ-#V^b2_rw4Jqx__R%#maJ3mK zXjRKw=Vuql4UOPyf;htlSM#fN6&f}K#w;6m;%|&p8n!QygBi^u)p}`I-2cdl_0dK& zZfO_|su8Ay`!-M3eabX)8)|2cu&q!oZ%`&Tuv9D{A5+6n-my4{31xm+4hUw{;ziY) z%#M=N+m{D9dc)JLRqFJao)D^;ZTTBx`o!Rb~M%_*Wn6ra{V0 z`FQv3Ngm*>+RN{r?os)+iA-8KaE{V14LfaO6hj(iW~M3*6Ik^T9lfa<{1Y_Y6`Vi# zX4fd$hE1$Z=vj`jp^+RaRt?f72e8ym#5QY>wEn%nru~^GN{T2{)%J#(!?Flo&b_{T zf~(|K(`HDiq)x$oPd?IwkK>(z->7!wqZLx{}fS%q7Yln#HaVM zm3V2K6UM(%A%usjzGJ95?}Kf<74lje^n3%t`PR7|Y$OafC8$0W`TW^cgd-PBTtGF{ zjB7iAbaCVi!`J>ab+?T^U1Lt^rfaIzFfy>2jq1yE{`|Y5g}>2hFGRV(Ygo4oo&_UmKRAzZ z&hU_l{nXRbozO1f`O2;(i>@50v{#_MxVE#T`N`3e{SVo2YV`i(XM?2EKAH`^`dQ(U z?Gfz8L1`glzn3(k!kEPE%&tWbUw1C^Q&uQv&{bD$zE`yi&(q5Lko?zzI(|D#|DRTp z$WISh-z7RyCSp^Ob=4dlllx@`B`*b#kV`^G*hDX!6cNFN#O%bQJVNGDc0-HnwVwRd zEM4aXb8i5r-R~=udFG^w^8D2lig?uc%0)}#x{^3qe<@))B%NEFrN76h|5kCQ^#&bQ z(hy8RUF>0$^$zL%6`5YLZFI20UJVUuWW#pYetk(Tv_}%TB+2_ZmbR;89fM#a{A&c- zOfgCsn`JZ?mhY>ILGHAe+Ssn7GIja@-Ou)HWtM+3YAj?6*)Yuf5kN`{ zi<>M{Sl`MxZ_P{ubLu>@3H^~c9g6VM2xLta=XfGV;5hWXe!?yr=(_LL%GfTY>_`*( zX0MqNT@%Mp6clX$$Wv!8uq>GiUe{ZHj8`;nNmm6s-*;lb*I@3d3&({NoEhrSQ%UdEjhx(X?V7SmF*jo0NgCg{Q-{kq0)c*$eNLG5kjDRGhgcm(y?v?!j7b z&Pkh`Nrm!N0F%6dP&t`?-zKNbsdu#d6~vAs5$89gGsO<`J7V~Lg`?dN_I_>(}+K&Z*2Yu}rP!HgoLbOoY7W>ornq4dhu>2R@k-CT$H)&IBV*mzJAF*tkf z4jDgC@aV`}G0)!on@Z9J zT#p6Dg*vJ8*h9LQj>tQbdSaSXbV9KrC2yPS-^vHNlyCfAUU+iZXPlTu?={KB0 z=5bS>dUS$@Bbyr}yR7_YvWm<2!7_2%ooa|_%C$T_Hnn~pR%*P2i>v_OpU&72^~lTr z=kf^}NJ%d9vd%T2{Mn{W_|wvC8JEv^lLC!7yeFNfRl*Kt#6Lplw262C`ygsj-u!k% zE|qoP(+k`28^R;{X;`NxcN)h+5PI>{0s}UDHTY3Xj^H zZ=b~7_q=|oBTfOvLtKA1X(p;{eFEmdYiWFoF@?jX!8>9JPITpR^~kx-FKrLX=X)`d zT>78XjRf)O%dk;c`J*?rEx%5FW2P9l>28hl3|EZ~nR^O_%XSURU*+?usMW$7@(TOh zz7sU|(Bee1*IgXrA@$<2K>Bczi!SsQ-P2r0>(rKp4Z%5hP8r`Mutq;S z;wiNH^wdNcM_q|-_0|U`yg+xe$u=;AM+GqKCVRO2JUod|H~Ku^gW=3KR^wILuu0zA zX2BPteaQ@`DLz+rQC)|3C;?89%-<%mo%Q6bT4AQA*rLe&NsMw5mb?gQ3}rb5Z_F}6 zxo8*mWPHA)a*pEAF68{3*4)o4+8yXK#fe%>INu1Gd4zBkz94@*t#5{0Y9w82z`RA| zF@hP1Pd!K$_F&CL;bMA=m@{;%&P>Rg8x3R(?8rSwt5tFJMBfc6a} zNd=u!fW80BtM{%^zR8&?qE)%C)lMhGD?1 zoEkc>h(mm(SGHe7qRv~+nVmItmu|`dwhng7(y*sj4T>{O>4V7==&4Wqi-CQ< z`b8=uVY;9Gmy{$t=b3O)G8Y~7k4jkeB_gA4s__RltUG#xFooiqxQgLj zL|?U!wxOne;wac6u~dEavqk#j1#?OT2?8~+MU5%?}Gy1*T0?K*Pnrwcqg6fL$#Jw?a72;cVWl8tITd)Aqhiv?eSgq^zsWk5J#Qu9_OlQA@!gR@ z`*zs5QbhkHkIL((_;!sq(8SN8SFf)U-yv!#!eg8bO~1Zu4~6l%O#PyaF&)F1__(3* zn;Yk}cNI#muLAos**7|JeabsYXv5$kg~5HAPX&U0mb_LI@s0n3e`r%`wv4;U43Eho z66Y_rk<*Nn`u?M%EL&wtxV~KgKm}8$nAw76PJKJO98mb z^XzHl;7vIHR2nU!mQO(ww8my6=~^u1p_axMnHbV^*B^PWS)+yvQo?TKJtJx(X9wrH zTJcE0v+>Oh+9PkYVu8_g_*8TU*(?>}{pZBfX+*;OawnTUUj?!M)^JWWHTQ{h7G>$H zz|$m8z@0iZb95tfh=cSB_5lg7q;Mi-j;3Lwy;6-#JX|FYOzV`H2(;DunvLdk;5#_kjk9Ko>ib~=i}O`pI0pVZ;LJ9xizVaF8RQ~ zIo$>)D!`auIoTGWWb5)f>kp3-!w@651;T7|Bi0|e2@Pb$gi4L!1r|{-qXL_cq45bq z+vmNZ+vDOwbxQ-~-WB}KxFI`}$)0^pDG^W3;!%)NhIF$m!GYMjkglY>D`(H))AevB zt#u#g>q(6=PS&oIh=7wXKDsp()iZP(K(;fVl;6l8B^~!KCM!SRBWe|BUz8H8$Q>2D z!(fVZ*8b|__v=+S$oJRug6yc{OB+KgSMDORkS9pnW z0fmDNT@Iw2$Ih>_$Y+Wl?>-r2)SD@W(9(T;qm~iFG0II3Zwkw#A!o0mXOS-*FOI3< z2$;2>okHGe7zyS*&lLX?gca|VM@=3NL_dXzB zq5KmftdKlM&3pq=y2s9M3{|-N1k0I!T$&W~Kxdmbk_A4^Hf!;XzKX@&+5k zeN!U&An(c?Tu)B|q(E$qvpx3L>a9o#DZ_aYZy;`5;--r5p1(EiEs1$

m-Yv|uv1w-Rc3XSU@52?tIOJ0?gG~DOS>Hq#m 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 QL+>TK%$CA9dxt~#wwUFt*ZbT9t?h= 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%0D2o#&rxKKCcln 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 diff --git a/packages/extension/package.json b/packages/extension/package.json index d34c570d..7386566d 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -29,7 +29,6 @@ "@vitejs/plugin-react": "^4.2.1", "bestzip": "^2.2.1", "cross-env": "^7.0.3", - "typescript": "~5.6.3", "vite": "^5.4.3", "vite-plugin-web-extension": "^4.3.1", "webextension-polyfill": "^0.10.0" diff --git a/packages/extension/src/content/graph.ts b/packages/extension/src/content/graph.ts new file mode 100644 index 00000000..0beec228 --- /dev/null +++ b/packages/extension/src/content/graph.ts @@ -0,0 +1,1166 @@ +console.log("graph.ts"); +// Types first +type Operation = { + type: 'add' | 'remove'; + count: number; + timestamp?: number; +}; +type HistoryPoint = { x: number; y: number; operationType: Operation['type'] | null }; +type ExcludeConfig = { excludeChildNodes: boolean }; + +// Add performance measurement types +type PerformanceMetrics = { + lastLCP: number | null; + lastCLS: number | null; + lastINP: number | null; + script: number; +}; + +// Add arrays to store metrics +const performanceMetrics: PerformanceMetrics[] = []; +const MAX_METRICS_SAMPLES = 30; + +// Add load state tracking +let isPageLoaded = false; + +// Add tracking for max values +let maxMetrics = { + lastLCP: null as number | null, + lastCLS: 0, + lastINP: null as number | null, + script: 0 +}; + +// Add LCP collection state +let lcpEntries: { size: number, startTime: number }[] = []; +const LCP_COLLECTION_TIME = 8000; // 8 seconds to collect LCP data +let lcpCollectionTimeout: number | null = null; + +// Add LCP state tracking +let lcpFinalized = false; + +// Add debug logging +const debugLCP = (msg: string, data?: any) => { + console.log(`[LCP Debug] ${msg}`, data || ''); +}; + +// Add valid LCP element types +const VALID_LCP_ELEMENTS = new Set([ + 'IMG', + 'SVG', + 'VIDEO', + 'CANVAS', + 'PICTURE' +]); + +// Add helper to check if element is visible +const isElementVisible = (element: Element): boolean => { + if (!element.getBoundingClientRect) return false; + const rect = element.getBoundingClientRect(); + return ( + rect.width > 0 && + rect.height > 0 && + window.getComputedStyle(element).visibility !== 'hidden' && + window.getComputedStyle(element).display !== 'none' + ); +}; + +// Separate observers for each metric +const lcpObserver = new PerformanceObserver((list) => { + if (lcpFinalized) return; + + const entries = list.getEntries(); + entries.forEach(entry => { + const lcp = entry as PerformanceEntry & { + element?: Element, + size: number, + renderTime?: number, + loadTime: number, + startTime: number + }; + + if (lcp.element && lcp.size > 0) { + const time = lcp.renderTime || lcp.loadTime || lcp.startTime; + + // Update if this is a larger contentful paint + if (!maxMetrics.lastLCP || time > maxMetrics.lastLCP) { + maxMetrics.lastLCP = time; + performanceMetrics[0] = { ...maxMetrics }; + debugLCP('New LCP:', { time, size: lcp.size }); + } + } + }); +}); + +const clsObserver = new PerformanceObserver((list) => { + const entries = list.getEntries(); + entries.forEach(entry => { + if (!(entry as LayoutShift).hadRecentInput) { + maxMetrics.lastCLS = (maxMetrics.lastCLS || 0) + (entry as LayoutShift).value; + performanceMetrics[0] = { ...maxMetrics }; + } + }); +}); + +// Update INP tracking state +let inpScores: number[] = []; +const INP_PERCENTILE = 0.75; // 75th percentile for INP + +// Update INP observer +const inpObserver = new PerformanceObserver((list) => { + const entries = list.getEntries(); + entries.forEach(entry => { + debugLCP('INP Entry:', { + duration: entry.duration, + type: entry.entryType, + name: (entry as any).name + }); + + // Track all valid interactions + if (entry.duration > 0) { + inpScores.push(entry.duration); + + // Calculate INP as the 98th percentile + const sortedScores = [...inpScores].sort((a, b) => b - a); + const percentileIndex = Math.floor(sortedScores.length * 0.98); + const newINP = sortedScores[percentileIndex] || sortedScores[0]; + + maxMetrics.lastINP = newINP; + performanceMetrics[0] = { ...maxMetrics }; + } + }); +}); + +// Update observer registration to handle both first-input and event +try { + // Register for first-input + inpObserver.observe({ + entryTypes: ['first-input'], + buffered: true + } as PerformanceObserverInit); + + // Register for event timing + const eventObserver = new PerformanceObserver((list) => { + const entries = list.getEntries(); + entries.forEach(entry => { + if (entry.duration > 0) { + inpScores.push(entry.duration); + const maxDuration = Math.max(...inpScores); + maxMetrics.lastINP = maxDuration; + performanceMetrics[0] = { ...maxMetrics }; + } + }); + }); + + eventObserver.observe({ + entryTypes: ['event'], + buffered: true + } as PerformanceObserverInit); +} catch (e) { + console.warn('Failed to register performance observers:', e); +} + +// Keep only this observer initialization in the load event +window.addEventListener('load', () => { + // Initialize metrics array + performanceMetrics[0] = maxMetrics; + + // Start observers + lcpObserver.observe({ + entryTypes: ['largest-contentful-paint'], + buffered: true + }); + + clsObserver.observe({ + entryTypes: ['layout-shift'], + buffered: true + }); + + inpObserver.observe({ + entryTypes: ['first-input', 'interaction'], + buffered: true + } as PerformanceObserverInit); + + // Set timeout to finalize LCP + setTimeout(() => { + lcpFinalized = true; + lcpObserver.disconnect(); + }, LCP_COLLECTION_TIME); +}); + +// Add measurement function +const measurePerformance = () => { + const now = performance.now(); + + // Create performance marks + performance.mark('measure-start'); + + // Force layout calculation + document.body.offsetHeight; + + // Measure paint and layout + const metrics: PerformanceMetrics = { + lastLCP: null, + lastCLS: null, + lastINP: null, + script: 0 + }; + + performance.mark('measure-end'); + const measure = performance.measure('total', 'measure-start', 'measure-end'); + metrics.script = measure.duration; + + performanceMetrics.push(metrics); + if (performanceMetrics.length > MAX_METRICS_SAMPLES) { + performanceMetrics.shift(); + } + + // Clear marks and measures + performance.clearMarks(); + performance.clearMeasures(); +}; + +// Add type definition for LayoutShift +interface LayoutShift extends PerformanceEntry { + value: number; + hadRecentInput: boolean; +} + +// Visual Configuration first +const VISUAL = { + CANVAS: { + WIDTH_RATIO: 0.25, + HEIGHT_RATIO: 0.20, + MIN_WIDTH: 400, + MIN_HEIGHT: 200, + } as { + WIDTH_RATIO: number, + HEIGHT_RATIO: number, + MIN_WIDTH: number, + MIN_HEIGHT: number + }, + STYLE: { + COLORS: { + GRID: "rgba(75, 75, 106, 0.4)", + LINE: "#b975f9", + GLOW: "rgba(185, 117, 249, 0.8)", + BACKGROUND: "#0f0f17", + STATUS: { + ACTIVE: "rgba(185, 117, 249, 0.8)", + INACTIVE: "rgba(185, 117, 249, 1)", + }, + }, + DOT: { + RADIUS: 4, + MARGIN: 16, + }, + }, +} as const; + +// Animation Configuration second +const ANIMATION = { + DURATION: { + SPIKE: 1000, + RETURN: 800, + DELAY: 300, + }, + GRID: { + SPEED: 2, + SIZE: 32, + }, + LINE: { + SPEED: 2, + }, + SPIKE: { + MIN_HEIGHT: 4, + MAX_HEIGHT: 200, + MULTIPLIER: 2, + SCALE_FACTOR: 0.8 + }, + BATCH_SIZE: 1, + EASE: { + OPERATION: 0.05, + RETURN: 0.02, + IDLE: 0.02 + } +} as const; + +// Performance Configuration +const PERFORMANCE = { + SCROLL: { + VELOCITY_THRESHOLD: 30, + SUSPEND_DELAY: 150, + BATCH_SIZE: 100, + FPS_LIMIT: 1000 / 30, + DETECTION_THRESHOLD: 5, + COOLDOWN: 100, + MIN_DELTA: 50, + FAST_SCROLL_FPS: 1000 / 10, + }, + FRAME: { + BUDGET: 16.67, + SKIP_THRESHOLD: 20, + MAX_SKIP_COUNT: 3, + THROTTLE_DELAY: 16, + SCROLL_THROTTLE: 32, + }, +}; + +// Configuration for exclusions +const EXCLUDED_IDS: Record = { + "react-scan-backdrop": { excludeChildNodes: true }, + "react-scan-toast": { excludeChildNodes: true }, + "react-scan-toolbar-root": { excludeChildNodes: true }, + "react-scan-inspect-canvas": { excludeChildNodes: true }, + "react-scan-extension-button": { excludeChildNodes: true }, + "react-scan-graph": { excludeChildNodes: true }, +}; + +const EXCLUDED_CLASSNAMES: Record = { + "exclude-class": { excludeChildNodes: true }, + "partial-exclude-class": { excludeChildNodes: false }, +}; + +const EXCLUDED_DATA_ATTRS: Record = { + "data-exclude": { excludeChildNodes: true }, + "data-partial-exclude": { excludeChildNodes: false }, +}; + +const EXCLUDED_TAGS: Record = { + SCRIPT: { excludeChildNodes: true }, + STYLE: { excludeChildNodes: true }, + HEAD: { excludeChildNodes: true }, + HTML: { excludeChildNodes: false }, // Include child nodes +}; + +const isExcluded = (el: Element): boolean => { + // Check if the element matches exclusion by ID + if (EXCLUDED_IDS[el.id]?.excludeChildNodes) return true; + + // Check if the element matches exclusion by class name + if (Array.from(el.classList).some((cls) => EXCLUDED_CLASSNAMES[cls]?.excludeChildNodes)) return true; + + // Check if the element matches exclusion by tag name + if (EXCLUDED_TAGS[el.tagName]?.excludeChildNodes) return true; + + // Check if the element matches exclusion by data attributes + if (Array.from(el.attributes).some((attr) => EXCLUDED_DATA_ATTRS[attr.name]?.excludeChildNodes)) return true; + + return false; +}; + +let rafId: number | null = null; +let lastDrawTime = performance.now(); + +let gridOffset = 0; +let currentY = VISUAL.CANVAS.MIN_HEIGHT / 2; +let targetY = VISUAL.CANVAS.MIN_HEIGHT / 2; +let isTracking = false; +let isAnimating = false; +let lastSpikeTime = 0; +let currentOperation: 'add' | 'remove' | null = null; +let lastFrameTime = performance.now(); +let isStatusActive = false; +let pendingOperations: Operation[] = []; +let lastElementCount = 0; +let isDragging = false; +let dragStartX = 0; +let dragStartY = 0; + +// History arrays +const paintTimes: number[] = []; +const positionHistory: HistoryPoint[] = []; +let MAX_HISTORY = Math.floor(VISUAL.CANVAS.MIN_WIDTH / ANIMATION.GRID.SPEED); + +// Storage and position +const STORAGE_KEY = 'react-scan-graph-position'; +let initialX: number; +let initialY: number; + +// State variables +let scrollState = { + timer: null as number | null, + minimalMode: false, + mutationBuffer: [] as MutationRecord[], + lastScrollTime: performance.now() +}; + +// Add near other state variables +let elementCache: Element[] = []; +let lastCacheTime = 0; + +// Add debounce for mutation processing +const MUTATION_DEBOUNCE = 32; // Faster response to changes + +// Add near other state variables +const MAX_PENDING_OPERATIONS = 50; +const MAX_PAINT_TIMES = 30; + +// Add these constants +const MUTATION_BATCH = { + WINDOW: 100, // Batch mutations within 100ms window + MAX_DELAY: 500, // Maximum time to wait before processing +} as const; + +// Add near other state variables +let mutationTimeout: number | null = null; + +// Add max limits to prevent memory leaks +const MAX_BUFFER_SIZE = 1000; +const MAX_PENDING_OPS = 100; + +// Cache DOM queries +let lastQueryTime = 0; +const QUERY_CACHE_DURATION = 100; // ms + +// Add visual dimensions storage +const VISUAL_STORAGE_KEY = 'react-scan-graph-dimensions'; + +// Function to save visual dimensions +const saveVisualDimensions = (width: number, height: number) => { + try { + localStorage.setItem(VISUAL_STORAGE_KEY, JSON.stringify({ width, height })); + } catch (e) { + console.warn('Failed to save graph dimensions:', e); + } +}; + +// Function to load visual dimensions +const loadVisualDimensions = () => { + try { + const saved = localStorage.getItem(VISUAL_STORAGE_KEY); + if (saved) { + const { width, height } = JSON.parse(saved); + return { + width: Math.max(VISUAL.CANVAS.MIN_WIDTH, width), + height: Math.max(VISUAL.CANVAS.MIN_HEIGHT, height) + }; + } + } catch (e) { + console.warn('Failed to load graph dimensions:', e); + } + return { + width: VISUAL.CANVAS.MIN_WIDTH, + height: VISUAL.CANVAS.MIN_HEIGHT + }; +}; + +// Utility functions +const savePosition = (x: number, y: number) => { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ x, y })); + } catch (e) { + console.warn('Failed to save graph position:', e); + } +}; + +const loadPosition = (canvasWidth: number, canvasHeight: number): { x: number, y: number } => { + try { + const saved = localStorage.getItem(STORAGE_KEY); + if (saved) { + const { x, y } = JSON.parse(saved); + return { + x: Math.min(Math.max(0, x), window.innerWidth - canvasWidth), + y: Math.min(Math.max(0, y), window.innerHeight - canvasHeight) + }; + } + } catch (e) { + console.warn('Failed to load graph position:', e); + } + return { + x: 16, + y: window.innerHeight - canvasHeight - 16 + }; +}; + +// Canvas initialization +const canvas = document.createElement("canvas"); +canvas.id = "react-scan-graph"; + +// Add near other state variables at the top +let currentDimensions = { + width: VISUAL.CANVAS.MIN_WIDTH, + height: VISUAL.CANVAS.MIN_HEIGHT +}; + +// Initialize with loaded dimensions +const initialDimensions = loadVisualDimensions(); +currentDimensions = { + width: initialDimensions.width, + height: initialDimensions.height +}; + +canvas.width = currentDimensions.width; +canvas.height = currentDimensions.height; +canvas.style.width = `${currentDimensions.width}px`; +canvas.style.height = `${currentDimensions.height}px`; + +// Load initial position after canvas creation +const savedPosition = loadPosition(canvas.width, canvas.height); +initialX = savedPosition.x; +initialY = savedPosition.y; + +// Set canvas position and styles +canvas.style.position = "fixed"; +canvas.style.top = `${initialY}px`; +canvas.style.left = `${initialX}px`; +canvas.style.borderRadius = "8px"; +canvas.style.backgroundColor = VISUAL.STYLE.COLORS.BACKGROUND; +canvas.style.boxShadow = "0 0 50px rgba(185, 117, 249, 0.15)"; +canvas.style.border = "1px solid rgba(185, 117, 249, 0.4)"; +canvas.style.zIndex = "2147483646"; +canvas.style.cursor = "move"; +canvas.style.opacity = "0"; +canvas.style.transition = "opacity 0.5s ease"; + +// Add fade-in effect +setTimeout(() => { + canvas.style.opacity = "1"; +}, 100); + +// Ensure document.documentElement exists before appending +if (document.documentElement) { + document.documentElement.appendChild(canvas); +} else { + document.addEventListener('DOMContentLoaded', () => { + document.documentElement.appendChild(canvas); + }); +} + +const ctx = canvas.getContext("2d")!; +ctx.font = `11px Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace`; + +// Create gradient +const backgroundGradient = (() => { + const gradient = ctx.createLinearGradient(0, 0, 0, VISUAL.CANVAS.MIN_HEIGHT); + gradient.addColorStop(0, "rgba(185, 117, 249, 0.15)"); + gradient.addColorStop(1, "rgba(185, 117, 249, 0)"); + return gradient; +})(); + +// Optimize gradient creation +const createGradients = () => { + const lineGradient = ctx.createLinearGradient(0, 0, 0, VISUAL.CANVAS.MIN_HEIGHT); + lineGradient.addColorStop(0, VISUAL.STYLE.COLORS.LINE); + lineGradient.addColorStop(1, "rgba(185, 117, 249, 0.6)"); + return { lineGradient }; +}; + +const { lineGradient } = createGradients(); + +// Add path caching +let cachedLinePath: Path2D | null = null; +let shouldUpdatePath = true; + +// Optimize line drawing with path caching +const updateLinePath = () => { + if (!shouldUpdatePath) return; + + const path = new Path2D(); + path.moveTo(currentDimensions.width / 2, currentY); + + positionHistory.forEach((point, i) => { + const x = currentDimensions.width / 2 - (i * ANIMATION.GRID.SPEED); + if (x < 0) return; + path.lineTo(x, point.y); + }); + + cachedLinePath = path; + shouldUpdatePath = false; +}; + +// Drawing functions +const drawGrid = () => { + ctx.strokeStyle = VISUAL.STYLE.COLORS.GRID; + ctx.lineWidth = 1; + ctx.setLineDash([1, 2]); + + for (let x = currentDimensions.width + (gridOffset % ANIMATION.GRID.SIZE); x >= 0; x -= ANIMATION.GRID.SIZE) { + ctx.beginPath(); + ctx.moveTo(x, 0); + ctx.lineTo(x, currentDimensions.height); + ctx.stroke(); + } + + for (let y = 0; y <= currentDimensions.height; y += ANIMATION.GRID.SIZE) { + ctx.beginPath(); + ctx.moveTo(0, y); + ctx.lineTo(currentDimensions.width, y); + ctx.stroke(); + } + + ctx.setLineDash([]); +}; + +// Add these constants +const FRAME_SAMPLE_SIZE = 60; // 1 second worth of frames at 60fps +const MAX_FPS = 60; + +// Add helper function near other utility functions +const formatNumber = (num: number): string => { + return new Intl.NumberFormat('en-US').format(num); +}; + +// Update drawStats function +const drawStats = () => { + const LEFT_MARGIN = 18; + const TOP_MARGIN = 32; + const LINE_SPACING = 24; + + ctx.shadowBlur = 0; + ctx.font = `400 13px Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace`; + ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; + + // Elements count with formatting + ctx.fillText(`Total DOM Elements: ${formatNumber(lastElementCount)}`, LEFT_MARGIN, TOP_MARGIN); + + // Frame time and FPS + const avgFrameTime = paintTimes.length > 0 + ? paintTimes.reduce((sum, time) => sum + time, 0) / paintTimes.length + : 16.67; + const fps = Math.round(1000 / avgFrameTime); + const clampedFps = Math.min(60, Math.max(0, fps)); + const roundedTime = Math.round(avgFrameTime * 100) / 100; + ctx.fillText(`Frame Time: ${roundedTime}ms (${clampedFps} FPS)`, LEFT_MARGIN, TOP_MARGIN + LINE_SPACING); + + // Text length counter with formatting + const textLength = Array.from(document.documentElement.querySelectorAll('*')) + .reduce((sum, el) => sum + (el.textContent?.length || 0), 0); + ctx.fillText(`Characters: ${formatNumber(textLength)}`, LEFT_MARGIN, currentDimensions.height - LINE_SPACING); + + // Calculate averages + const avgMetrics = performanceMetrics.length > 0 + ? { + lastLCP: performanceMetrics[performanceMetrics.length - 1]?.lastLCP || 0, + lastCLS: performanceMetrics[performanceMetrics.length - 1]?.lastCLS || 0, + lastINP: performanceMetrics[performanceMetrics.length - 1]?.lastINP || 0, + script: performanceMetrics[performanceMetrics.length - 1]?.script || 0, + } + : { lastLCP: 0, lastCLS: 0, lastINP: 0, script: 0 }; + + // Show performance metrics + const latestMetrics = performanceMetrics[performanceMetrics.length - 1]; + ctx.fillText( + `LCP: ${formatMetric(latestMetrics?.lastLCP)} CLS: ${formatMetric(latestMetrics?.lastCLS)} INP: ${formatMetric(latestMetrics?.lastINP)}`, + LEFT_MARGIN, + currentDimensions.height - LINE_SPACING * 2 + ); +}; + +const drawStatusDot = () => { + ctx.save(); + ctx.beginPath(); + ctx.shadowBlur = scrollState.minimalMode ? 0 : 15; + ctx.shadowColor = VISUAL.STYLE.COLORS.STATUS.ACTIVE; + ctx.fillStyle = scrollState.minimalMode ? VISUAL.STYLE.COLORS.STATUS.INACTIVE : VISUAL.STYLE.COLORS.STATUS.ACTIVE; + ctx.arc( + currentDimensions.width - VISUAL.STYLE.DOT.MARGIN, + VISUAL.STYLE.DOT.MARGIN, + VISUAL.STYLE.DOT.RADIUS, + 0, + Math.PI * 2 + ); + ctx.fill(); + ctx.restore(); +}; + +// Update the position history handling +const updatePositionHistory = () => { + // Always add a new point, even without DOM changes + positionHistory.unshift({ + x: currentDimensions.width / 2, + y: currentY, + operationType: currentOperation + }); + + // Remove points that are off-screen + if (positionHistory.length > MAX_HISTORY) { + positionHistory.pop(); + } + + shouldUpdatePath = true; +}; + +// Update drawLines function +const drawLines = () => { + ctx.save(); + ctx.lineWidth = 2; + ctx.strokeStyle = lineGradient; + ctx.shadowColor = VISUAL.STYLE.COLORS.GLOW; + ctx.shadowBlur = 15; + + // Draw the main line + updateLinePath(); + if (cachedLinePath) { + ctx.translate(-(performance.now() % ANIMATION.LINE.SPEED), 0); + ctx.stroke(cachedLinePath); + } + ctx.restore(); + + ctx.beginPath(); + ctx.fillStyle = VISUAL.STYLE.COLORS.LINE; + ctx.shadowColor = VISUAL.STYLE.COLORS.GLOW; + ctx.shadowBlur = 15; + ctx.arc(currentDimensions.width / 2, currentY, 3, 0, Math.PI * 2); + ctx.fill(); +}; + +// Simplify drawChart to maintain constant animation +const drawChart = () => { + performance.mark('frame-start'); + if (!ctx) return; + + // Request next frame first + const now = performance.now(); + const actualFrameTime = now - lastFrameTime; + + // Track real frame time + if (actualFrameTime > 0) { // Only track valid frame times + paintTimes.push(actualFrameTime); + if (paintTimes.length > 30) { + paintTimes.shift(); + } + } + + lastFrameTime = now; + rafId = requestAnimationFrame(drawChart); + + // Skip if too soon + if (actualFrameTime < 16) return; + + // Drawing operations + ctx.save(); + + + ctx.clearRect(0, 0, currentDimensions.width, currentDimensions.height); + ctx.fillStyle = backgroundGradient; + ctx.fillRect(0, 0, currentDimensions.width, currentDimensions.height); + + drawGrid(); + gridOffset -= ANIMATION.GRID.SPEED; + + const ease = currentOperation ? ANIMATION.EASE.OPERATION + : targetY === currentDimensions.height / 2 ? ANIMATION.EASE.RETURN + : ANIMATION.EASE.IDLE; + const distance = targetY - currentY; + currentY += distance * ease; + + updatePositionHistory(); + drawLines(); + drawStats(); + drawStatusDot(); + ctx.restore(); + + performance.measure('frame', 'frame-start'); +}; + +// Simplify scroll handler +const handleScroll = () => { + if (scrollState.timer !== null) { + clearTimeout(scrollState.timer); + } + + scrollState.minimalMode = true; + + scrollState.timer = window.setTimeout(() => { + scrollState.minimalMode = false; + if (scrollState.mutationBuffer.length > 0) { + processMutationBatch(scrollState.mutationBuffer); + scrollState.mutationBuffer = []; + } + }, 150); +}; + +// DOM observation +const countElements = () => { + const now = performance.now(); + if (now - lastQueryTime < QUERY_CACHE_DURATION) { + return lastElementCount; + } + lastQueryTime = now; + try { + const elements = document.documentElement.querySelectorAll('*'); + let count = 0; + + elements.forEach(el => { + if (el.nodeType === Node.ELEMENT_NODE && !isExcluded(el)) { + count++; + } + }); + + return count; + } catch (error) { + console.warn('Error counting elements:', error); + return lastElementCount; // Return last known count on error + } +}; + +const initializeElementCount = () => { + if (document.documentElement) { + lastElementCount = countElements(); + } +}; + +// Update processNextOperation to handle batches better +const processNextOperation = () => { + if (pendingOperations.length === 0 || isAnimating) return; + + isAnimating = true; + const operation = pendingOperations.shift()!; + currentOperation = operation.type; + + // Calculate height with better scaling and bounds + const maxAllowedHeight = currentDimensions.height / 2 - 16; // Leave margin + const baseHeight = Math.min( + maxAllowedHeight, + Math.log(operation.count + 1) * ANIMATION.SPIKE.MULTIPLIER * 8 + ); + + const spikeHeight = Math.max( + ANIMATION.SPIKE.MIN_HEIGHT, + Math.min(maxAllowedHeight, baseHeight) + ); + + // Set position relative to canvas center + const centerY = currentDimensions.height / 2; + currentY = operation.type === 'add' + ? centerY - spikeHeight + : centerY + spikeHeight; + targetY = currentY; + + // Record position + updatePositionHistory(); + + // Reset after fixed duration + setTimeout(() => { + currentOperation = null; + currentY = currentDimensions.height / 2; + targetY = currentY; + updatePositionHistory(); + + setTimeout(() => { + isAnimating = false; + if (pendingOperations.length > 0) { + processNextOperation(); + } + }, 16); // Minimal delay between operations + }, 32); // Short duration for each spike +}; + +// Event handlers +const handleDragStart = (e: MouseEvent) => { + isDragging = true; + dragStartX = e.clientX - initialX; + dragStartY = e.clientY - initialY; + canvas.style.transition = 'none'; +}; + +const handleDragMove = (e: MouseEvent) => { + if (!isDragging) return; + + const newX = Math.max(0, Math.min(window.innerWidth - canvas.width, e.clientX - dragStartX)); + const newY = Math.max(0, Math.min(window.innerHeight - canvas.height, e.clientY - dragStartY)); + + canvas.style.left = `${newX}px`; + canvas.style.top = `${newY}px`; + initialX = newX; + initialY = newY; + + // Save position immediately during drag + savePosition(newX, newY); +}; + +const handleDragEnd = () => { + isDragging = false; + canvas.style.transition = 'box-shadow 0.3s ease'; + savePosition(initialX, initialY); +}; + +const handleResize = () => { + // Calculate new dimensions + const maxWidth = Math.floor(window.innerWidth * VISUAL.CANVAS.WIDTH_RATIO); + const maxHeight = Math.floor(window.innerHeight * VISUAL.CANVAS.HEIGHT_RATIO); + + currentDimensions = { + width: Math.max(VISUAL.CANVAS.MIN_WIDTH, maxWidth), + height: Math.max(VISUAL.CANVAS.MIN_HEIGHT, maxHeight) + }; + + // Update canvas + canvas.width = currentDimensions.width; + canvas.height = currentDimensions.height; + canvas.style.width = `${currentDimensions.width}px`; + canvas.style.height = `${currentDimensions.height}px`; + + // Update history size based on actual width + MAX_HISTORY = Math.floor(currentDimensions.width / ANIMATION.GRID.SPEED); + + // Clear and rebuild path cache + cachedLinePath = null; + shouldUpdatePath = true; + + // Calculate new position based on current position + initialX = Math.min(initialX, window.innerWidth - currentDimensions.width); + initialY = Math.min(initialY, window.innerHeight - currentDimensions.height); + + // Update canvas position + canvas.style.left = `${initialX}px`; + canvas.style.top = `${initialY}px`; + + // Save new position immediately + savePosition(initialX, initialY); + + // Recreate gradients with new dimensions + const gradient = ctx.createLinearGradient(0, 0, 0, currentDimensions.height); + gradient.addColorStop(0, "rgba(185, 117, 249, 0.15)"); + gradient.addColorStop(1, "rgba(185, 117, 249, 0)"); + Object.assign(backgroundGradient, gradient); + + const { lineGradient: newLineGradient } = createGradients(); + Object.assign(lineGradient, newLineGradient); + + // Force a full redraw + shouldUpdatePath = true; + drawChart(); +}; + +// Event listeners +canvas.addEventListener('mousedown', handleDragStart); +document.addEventListener('mousemove', handleDragMove); +document.addEventListener('mouseup', handleDragEnd); +window.addEventListener('resize', handleResize); + +// Initialize observers +const mutationObserver = new MutationObserver((mutations) => { + if (scrollState.minimalMode) { + scrollState.mutationBuffer.push(...mutations); + return; + } + + if (mutationTimeout) clearTimeout(mutationTimeout); + mutationTimeout = window.setTimeout(() => { + processMutationBatch(mutations); + }, MUTATION_DEBOUNCE); +}); + +// Clean up on window events +window.addEventListener('scroll', handleScroll, { passive: true }); +window.addEventListener('resize', handleResize); + +// Update initialization order +const initializeGraph = () => { + // Create and setup canvas first + if (document.documentElement) { + document.documentElement.appendChild(canvas); + } else { + document.addEventListener('DOMContentLoaded', () => { + document.documentElement.appendChild(canvas); + }); + } + + // Start animation + rafId = requestAnimationFrame(drawChart); + + // Delay observer initialization to avoid initial DOM noise + setTimeout(() => { + // Get initial count before starting observation + lastElementCount = countElements(); + + // Start observing after getting initial count + if (document.documentElement) { + mutationObserver.observe(document.documentElement, { + childList: true, + subtree: true, + attributes: false, + characterData: true, + characterDataOldValue: true + }); + } + }, 10); // Give the page time to settle +}; + +// Clear any existing initialization +if (rafId !== null) { + cancelAnimationFrame(rafId); +} + +// Update processMutationBatch function +const processMutationBatch = (mutations: MutationRecord[]) => { + if (isTracking) return; + isTracking = true; + + try { + const now = performance.now(); + performance.mark('mutation-start'); + + // Process mutations... + let changes = { + elementsRemoved: 0, + elementsAdded: 0, + hasInnerHTMLClear: false, + hasInnerHTMLAdd: false, + textChanges: 0 + }; + + mutations.forEach(mutation => { + if (mutation.type === 'childList') { + const target = mutation.target as Element; + const removedNodes = Array.from(mutation.removedNodes) + .filter(node => node.nodeType === Node.ELEMENT_NODE && !isExcluded(node as Element)); + const addedNodes = Array.from(mutation.addedNodes) + .filter(node => node.nodeType === Node.ELEMENT_NODE && !isExcluded(node as Element)); + + // Check for innerHTML clear + if (removedNodes.length > 0 && target.childNodes.length === 0) { + changes.hasInnerHTMLClear = true; + } + // Check for innerHTML add + else if (addedNodes.length > 0 && mutation.previousSibling === null && mutation.nextSibling === null) { + changes.hasInnerHTMLAdd = true; + } + + changes.elementsRemoved += removedNodes.length; + changes.elementsAdded += addedNodes.length; + } + else if (mutation.type === 'characterData') { + const oldText = mutation.oldValue || ''; + const newText = mutation.target.textContent || ''; + + if (oldText.trim() !== newText.trim()) { + // Compare lengths to determine if characters were added or removed + if (newText.length > oldText.length) { + // Characters were added + pendingOperations.push({ + type: 'add', + count: 1, // Small spike for text addition + timestamp: now + }); + } else if (newText.length < oldText.length) { + // Characters were removed + pendingOperations.push({ + type: 'remove', + count: 1, // Small spike for text removal + timestamp: now + }); + } + } + } + }); + + // Create operations in sequence + if (changes.hasInnerHTMLClear || changes.elementsRemoved > 0) { + pendingOperations.push({ + type: 'remove', + count: changes.elementsRemoved, + timestamp: now + }); + } + + // Add text changes as small spikes + if (changes.textChanges > 0) { + pendingOperations.push({ + type: 'add', + count: 1, // Use minimum height for text + timestamp: now + }); + } + + if (changes.hasInnerHTMLAdd || changes.elementsAdded > 0) { + pendingOperations.push({ + type: 'add', + count: changes.elementsAdded, + timestamp: now + }); + } + + if (!isAnimating && pendingOperations.length > 0) { + processNextOperation(); + } + + lastElementCount = countElements(); + + // Measure performance after DOM changes + performance.mark('mutation-end'); + const measure = performance.measure('mutation', 'mutation-start', 'mutation-end'); + + // Create new metrics while preserving web vitals + const metrics: PerformanceMetrics = { + lastLCP: maxMetrics.lastLCP, // Preserve LCP + lastCLS: maxMetrics.lastCLS, // Preserve CLS + lastINP: maxMetrics.lastINP, // Preserve INP + script: measure.duration + }; + + // Add metrics only if there were actual DOM changes + if (changes.elementsAdded > 0 || changes.elementsRemoved > 0 || changes.textChanges > 0) { + performanceMetrics[0] = metrics; // Update instead of push + } + } finally { + isTracking = false; + performance.clearMarks(); + performance.clearMeasures(); + } +}; + +// Start fresh +initializeGraph(); + +const cleanup = () => { + if (rafId) { + cancelAnimationFrame(rafId); + rafId = null; + } + mutationObserver.disconnect(); + resizeObserver.disconnect(); + if (scrollState.timer) { + clearTimeout(scrollState.timer); + scrollState.timer = null; + } + if (mutationTimeout) { + clearTimeout(mutationTimeout); + mutationTimeout = null; + } + canvas.remove(); + + // Reset all state + positionHistory.length = 0; + paintTimes.length = 0; + pendingOperations.length = 0; + lcpObserver.disconnect(); + clsObserver.disconnect(); + inpObserver.disconnect(); +}; + +window.addEventListener('unload', cleanup); + +// Add resize observer for more reliable size updates +const resizeObserver = new ResizeObserver(() => { + handleResize(); +}); +resizeObserver.observe(document.documentElement); + +const formatMetric = (value: number | null): string => { + if (value === null || isNaN(value)) return '---'; + + // Ensure value is a valid number + const numValue = Number(value); + + if (numValue < 0.01) return '< 0.01'; + + // LCP: show in seconds with 2 decimals + if (numValue > 1000) return `${(numValue / 1000).toFixed(2)}s`; + + // CLS: show up to 3 decimals + if (numValue < 1) return numValue.toFixed(3); + + // INP: show in ms without decimals + return `${Math.round(numValue)}ms`; +}; + +// Initialize metrics array with initial state +performanceMetrics[0] = { + lastLCP: null, + lastCLS: 0, + lastINP: null, + script: 0 +}; diff --git a/packages/extension/src/content/index.ts b/packages/extension/src/content/index.ts index 7e246f23..427a62bc 100644 --- a/packages/extension/src/content/index.ts +++ b/packages/extension/src/content/index.ts @@ -1,3 +1,5 @@ +import './graph'; + import styles from '../assets/css/styles.css?inline'; import { BroadcastSchema } from '../types/messages'; import { loadCss, broadcast } from '../utils/helpers'; diff --git a/packages/extension/src/inject/index.ts b/packages/extension/src/inject/index.ts index 58d01d5d..4b2c6b9d 100644 --- a/packages/extension/src/inject/index.ts +++ b/packages/extension/src/inject/index.ts @@ -3,7 +3,8 @@ import { getReactVersion, loadCss, broadcast } from '../utils/helpers'; import { CACHE_TTL, CACHE_NAME } from '../utils/constants'; const scriptsToInject = [ - 'https://unpkg.com/react-scan/dist/auto.global.js', + // 'https://unpkg.com/react-scan/dist/auto.global.js', + 'https://127.0.0.1:4000/auto.global.js', ]; const injectScript = (scriptURL: string, scriptContent: string) => { diff --git a/packages/scan/.gitignore b/packages/scan/.gitignore new file mode 100644 index 00000000..bd8176ff --- /dev/null +++ b/packages/scan/.gitignore @@ -0,0 +1 @@ +src/core/web/assets/css/styles.css diff --git a/packages/scan/package.json b/packages/scan/package.json index 1515210f..8f022a82 100644 --- a/packages/scan/package.json +++ b/packages/scan/package.json @@ -214,11 +214,14 @@ "auto.d.ts" ], "scripts": { - "build": "NODE_ENV=production tsup", + "build": "npm run build:css && NODE_ENV=production tsup", "postbuild": "pnpm copy-astro", "build:copy": "NODE_ENV=production tsup && cat dist/auto.global.js | pbcopy", "copy-astro": "cp -R src/core/monitor/params/astro dist/core/monitor/params", - "dev": "pnpm copy-astro & NODE_ENV=development tsup --watch", + "dev:css": "npx tailwindcss -i ./src/core/web/assets/css/styles.tailwind.css -o ./src/core/web/assets/css/styles.css --watch", + "dev:tsup": "NODE_ENV=development tsup --watch", + "dev": "pnpm copy-astro && npm-run-all --parallel dev:css dev:tsup", + "build:css": "npx tailwindcss -i ./src/core/web/assets/css/styles.tailwind.css -o ./src/core/web/assets/css/styles.css --minify", "lint": "eslint 'src/**/*.{ts,tsx}' --fix", "pack": "npm version patch && pnpm build && npm pack", "pack:bump": "bun scripts/bump-version.js && nr pack && echo $(pwd)/react-scan-$(node -p \"require('./package.json').version\").tgz | pbcopy", @@ -244,17 +247,17 @@ "tsx": "^4.0.0" }, "devDependencies": { + "@esbuild-plugins/tsconfig-paths": "^0.1.2", "@remix-run/react": "*", "@types/babel__core": "^7.20.5", - "@types/node": "^20.17.9", "@types/react": "^18.0.0", "@types/react-reconciler": "^0.28.8", "@types/react-router": "^5.1.0", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vercel/style-guide": "^6.0.0", - "eslint": "^8.0.0", + "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "next": "*", + "npm-run-all": "^4.1.5", + "postcss": "^8", "prettier": "^3.3.3", "publint": "^0.2.12", "react": "*", @@ -262,9 +265,10 @@ "react-reconciler": "^0.29.2", "react-router": "^5.0.0", "react-router-dom": "^5.0.0 || ^6.0.0 || ^7.0.0", + "tailwind-merge": "^2.5.5", + "tailwindcss": "^3.4.1", "terser": "^5.36.0", "tsup": "^8.0.0", - "typescript": "^5.0.0", "vitest": "^1.0.0" }, "peerDependencies": { diff --git a/packages/scan/postcss.config.mjs b/packages/scan/postcss.config.mjs new file mode 100644 index 00000000..2aa7205d --- /dev/null +++ b/packages/scan/postcss.config.mjs @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/packages/scan/src/cli.mts b/packages/scan/src/cli.mts index ebabd155..5dde434f 100644 --- a/packages/scan/src/cli.mts +++ b/packages/scan/src/cli.mts @@ -4,8 +4,8 @@ import { firefox, webkit, devices, - type Browser, - type BrowserContext, + Browser, + BrowserContext, } from 'playwright'; import mri from 'mri'; import { intro, confirm, isCancel, cancel, spinner } from '@clack/prompts'; diff --git a/packages/scan/src/core/index.ts b/packages/scan/src/core/index.ts index 5abbbbea..e3d75cc7 100644 --- a/packages/scan/src/core/index.ts +++ b/packages/scan/src/core/index.ts @@ -1,29 +1,32 @@ import type { Fiber } from 'react-reconciler'; import type * as React from 'react'; import { type Signal, signal } from '@preact/signals'; -import { getDisplayName, getTimings, getType, isCompositeFiber } from 'bippy'; -import { createInstrumentation, type Render } from './instrumentation'; +import { + getDisplayName, + getTimings, + getType, + isCompositeFiber, +} from 'bippy'; import { type ActiveOutline, flushOutlines, getOutline, type PendingOutline, -} from './web/outline'; -import { logIntro } from './web/log'; -import { initReactScanOverlay } from './web/overlay'; +} from '@web-utils/outline'; +import { logIntro } from '@web-utils/log'; import { createInspectElementStateMachine, type States, -} from './web/inspect-element/inspect-state-machine'; +} from '@web-inspect-element/inspect-state-machine'; +import { playGeigerClickSound } from '@web-utils/geiger'; +import { ICONS } from '@web-assets/svgs/svgs'; +import { isValidFiber, updateFiberRenderData, type RenderData } from 'src/core/utils'; +import { createInstrumentation, type Render } from './instrumentation'; +import styles from './web/assets/css/styles.css'; +import { initReactScanOverlay } from './web/overlay'; import { createToolbar } from './web/toolbar'; import type { InternalInteraction } from './monitor/types'; import { type getSession } from './monitor/utils'; -import { - isValidFiber, - type RenderData, - updateFiberRenderData, -} from './utils'; -import { playGeigerClickSound } from './web/geiger'; export interface Options { /** @@ -240,6 +243,8 @@ export const reportRender = (fiber: Fiber, renders: Array) => { if (prevRenderData) { prevRenderData.renders.push(...renders); + // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + prevRenderData.count += renders.length; } else { const { selfTime } = getTimings(fiber); @@ -259,6 +264,8 @@ export const reportRender = (fiber: Fiber, renders: Array) => { if (prevLegacyRenderData) { prevLegacyRenderData.renders.push(...renders); + // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + prevLegacyRenderData.count += renders.length; } else { const { selfTime } = getTimings(fiber); @@ -276,27 +283,67 @@ export const reportRender = (fiber: Fiber, renders: Array) => { export const start = () => { if (typeof window === 'undefined') return; - const options = ReactScanInternals.options.value; - const existingOverlay = document.querySelector('react-scan-overlay'); - if (existingOverlay) { + const existingRoot = document.querySelector('react-scan-root'); + if (existingRoot) { return; } - initReactScanOverlay(); - const overlayElement = document.createElement('react-scan-overlay') as any; - document.documentElement.appendChild(overlayElement); + // Create container for shadow DOM + const container = document.createElement('div'); + container.id = 'react-scan-root'; + + const shadow = container.attachShadow({ mode: 'open' }); + + const fragment = document.createDocumentFragment(); + + // add styles + const cssStyles = document.createElement('style'); + cssStyles.textContent = styles; + + // Create SVG sprite sheet node directly + const iconSprite = new DOMParser().parseFromString(ICONS, 'image/svg+xml').documentElement; + shadow.appendChild(iconSprite); + + + // add toolbar root + const root = document.createElement('div'); + root.id = 'react-scan-toolbar-root'; + root.className = 'absolute z-2147483647'; + + fragment.appendChild(cssStyles); + fragment.appendChild(root); + + shadow.appendChild(fragment); + + // Add container to document first (so shadow DOM is available) + document.documentElement.appendChild(container); + + const options = ReactScanInternals.options.value; + + const ctx = initReactScanOverlay(); + if (!ctx) return; + + createInspectElementStateMachine(shadow); - const ctx = overlayElement.getContext(); - createInspectElementStateMachine(); const audioContext = typeof window !== 'undefined' ? new (window.AudioContext || - // @ts-expect-error -- This is a fallback for Safari - window.webkitAudioContext)() + // @ts-expect-error -- This is a fallback for Safari + window.webkitAudioContext)() : null; - logIntro(); + if (!Store.monitor.value) { + const existingOverlay = document.querySelector('react-scan-overlay'); + if (existingOverlay) { + return; + } + const overlayElement = document.createElement('react-scan-overlay') as any; + + document.documentElement.appendChild(overlayElement); + + logIntro(); + } globalThis.__REACT_SCAN__ = { ReactScanInternals, @@ -350,7 +397,7 @@ export const start = () => { ReactScanInternals.instrumentation = instrumentation; if (options.showToolbar) { - createToolbar(); + createToolbar(shadow); } }; diff --git a/packages/scan/src/core/monitor/index.ts b/packages/scan/src/core/monitor/index.ts index 6cd314ae..f592d6b9 100644 --- a/packages/scan/src/core/monitor/index.ts +++ b/packages/scan/src/core/monitor/index.ts @@ -1,7 +1,7 @@ 'use client'; -import React from 'react'; import { getDisplayName, isCompositeFiber } from 'bippy'; import { type Fiber } from 'react-reconciler'; +import { useEffect } from 'preact/hooks'; import { type MonitoringOptions, ReactScanInternals, @@ -44,8 +44,7 @@ export const Monitoring = ({ Store.monitor.value.route = route; Store.monitor.value.path = path; - // eslint-disable-next-line import/no-named-as-default-member - React.useEffect(() => { + useEffect(() => { scanMonitoring({ enabled: true, }); diff --git a/packages/scan/src/core/monitor/params/next.ts b/packages/scan/src/core/monitor/params/next.ts index 56ef2f13..6288fc81 100644 --- a/packages/scan/src/core/monitor/params/next.ts +++ b/packages/scan/src/core/monitor/params/next.ts @@ -1,13 +1,16 @@ 'use client'; -// adapted from vercel analytics import { useParams, usePathname, useSearchParams } from 'next/navigation.js'; -// import React from 'react'; import { createElement, Suspense } from 'react'; import { Monitoring as BaseMonitoring } from '..'; import { computeRoute } from './utils'; -// import { computeRoute } from '../utils'; -// does this work in pages and app router? Idk + +/** + * This hook works in both Next.js Pages and App Router: + * - App Router: Uses the new useParams() hook directly + * - Pages Router: useParams() returns empty object, falls back to searchParams + * This fallback behavior ensures compatibility across both routing systems + */ const useRoute = (): { route: string | null; path: string; @@ -37,10 +40,24 @@ export function MonitoringInner(props: { url?: string; apiKey: string }) { }); } -export function Monitoring(props: { url?: string; apiKey: string }) { - return createElement( - Suspense, - { fallback: null }, - createElement(MonitoringInner, props), - ); -} +/** + * The double 'use client' directive pattern is intentional: + * 1. Top-level directive marks the entire module as client-side + * 2. IIFE-wrapped component with its own directive ensures: + * - Component is properly tree-shaken (via @__PURE__) + * - Component maintains client context when code-split + * - Execution scope is preserved + * + * This pattern is particularly important for Next.js's module + * system and its handling of Server/Client Components. + */ +export const Monitoring = /* @__PURE__ */ (() => { + 'use client'; + return function Monitoring(props: { url?: string; apiKey: string }) { + return createElement( + Suspense, + { fallback: null }, + createElement(MonitoringInner, props), + ); + }; +})(); diff --git a/packages/scan/src/core/monitor/performance.ts b/packages/scan/src/core/monitor/performance.ts index 0501c96f..6d901b54 100644 --- a/packages/scan/src/core/monitor/performance.ts +++ b/packages/scan/src/core/monitor/performance.ts @@ -1,4 +1,4 @@ -/* eslint-disable prefer-named-capture-group */ + import { type Fiber } from 'react-reconciler'; import { getDisplayName } from 'bippy'; import { Store } from '../..'; @@ -29,9 +29,9 @@ const DEFAULT_FILTERS: PathFilters = { const FILTER_PATTERNS = { providers: [/Provider$/, /^Provider$/, /^Context$/], - hocs: [/^with[A-Z]/, /^forward(Ref)?$/i, /^Forward(Ref)?\(/], + hocs: [/^with[A-Z]/, /^forward(?:Ref)?$/i, /^Forward(?:Ref)?\(/], - containers: [/^(App)?Container$/, /^Root$/, /^ReactDev/], + containers: [/^(?:App)?Container$/, /^Root$/, /^ReactDev/], utilities: [ /^Fragment$/, @@ -83,8 +83,7 @@ const isMinified = (name: string): boolean => { const hasNoVowels = !/[aeiou]/i.test(name); const hasMostlyNumbers = (name.match(/\d/g)?.length ?? 0) > name.length / 2; const isSingleWordLowerCase = /^[a-z]+$/.test(name); - // eslint-disable-next-line no-useless-escape - const hasRandomLookingChars = /[\$_]{2,}/.test(name); + const hasRandomLookingChars = /[$_]{2,}/.test(name); const suspiciousTraits = [ hasNoVowels, @@ -129,7 +128,7 @@ function getCleanComponentName(component: any): string { const name = getDisplayName(component); if (!name) return ''; - return name.replace(/^(Memo|Forward(Ref)?|With.*?)\((.*?)\)$/, '$3'); + return name.replace(/^(?:Memo|Forward(?:Ref)?|With.*?)\((?.*?)\)$/, '$'); } function normalizePath(path: Array): string { diff --git a/packages/scan/src/core/monitor/utils.ts b/packages/scan/src/core/monitor/utils.ts index 6b8b23da..edb31efc 100644 --- a/packages/scan/src/core/monitor/utils.ts +++ b/packages/scan/src/core/monitor/utils.ts @@ -1,4 +1,4 @@ -import { onIdle } from '../web/utils'; +import { onIdle } from '../web/utils/helpers'; import { isSSR } from './constants'; import { Device, type Session } from './types'; diff --git a/packages/scan/src/core/web/assets/css/styles.tailwind.css b/packages/scan/src/core/web/assets/css/styles.tailwind.css new file mode 100644 index 00000000..aa25da68 --- /dev/null +++ b/packages/scan/src/core/web/assets/css/styles.tailwind.css @@ -0,0 +1,405 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* We will refactor this later */ +* { + outline: none !important; +} + +button { + @apply hover:bg-none; + @apply outline-none; + @apply border-none; + @apply transition-colors duration-150 ease-linear; + @apply cursor-pointer; +} + +/* + Using CSS content with data attributes is more performant than: + 1. React re-renders with JSX text content + 2. Direct DOM manipulation methods: + - element.textContent (creates/updates text nodes, triggers repaint) + - element.innerText (triggers reflow by computing styles & layout) + - element.innerHTML (heavy parsing, triggers reflow, security risks) + 3. Multiple data attributes with complex CSS concatenation + + This approach: + - Avoids React reconciliation + - Uses browser's native CSS engine (optimized content updates) + - Minimizes main thread work + - Reduces DOM operations + - Avoids forced reflows (layout recalculation) + - Only triggers necessary repaints + - Keeps pseudo-element updates in render layer +*/ +.with-data-text::before { + content: attr(data-text); +} + +.with-data-text-max-lines-5 { + &::before { + content: attr(data-text); + display: -webkit-box; + -webkit-line-clamp: 5; + -webkit-box-orient: vertical; + overflow: hidden; + } +} + + +/* Default scrollbar styles for all elements in shadow DOM */ +:host *::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +:host *::-webkit-scrollbar-track { + background: transparent; +} + +:host *::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; +} + +:host *::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); +} + +/* For Firefox */ +:host * { + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.1); +} + +/* @pivanov end */ + + +/* We will refactor this later */ +.react-scan-header-right { + display: flex; + gap: 4px; +} + +.react-scan-replay-button, +.react-scan-close-button { + display: flex; + align-items: center; + padding: 4px; + border: none; + border-radius: 4px; + color: #fff; + cursor: pointer; + transition: opacity 150ms ease; + position: relative; + overflow: hidden; + isolation: isolate; +} + +.react-scan-close-button { + background: rgba(255, 255, 255, 0.01); +} + +.react-scan-close-button:hover { + background: rgba(255, 255, 255, 0.15); +} + +.react-scan-replay-button { + background: rgba(142, 97, 227, 0.5) !important; +} + +.react-scan-replay-button.disabled { + opacity: 0.5; + pointer-events: none; +} + +.react-scan-replay-button:hover { + background: rgba(142, 97, 227, 0.25); +} + +.react-scan-replay-button::before { + content: ''; + position: absolute; + inset: 0; + transform: translateX(-100%); + animation: shimmer 2s infinite; + background: linear-gradient(to right, + transparent, + rgba(142, 97, 227, 0.3), + transparent); +} + +@keyframes shimmer { + 100% { + transform: translateX(100%); + } +} + + +/* We will refactor this later */ +#react-scan-toolbar { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + z-index: 999999999; +} + +.react-scan-inspector { + font-size: 13px; + color: #fff; + width: 100%; +} + +.react-scan-header { + padding: 8px 12px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + display: flex; + gap: 8px; + align-items: center; + justify-content: space-between; + background: #000; +} + +.react-scan-header-left { + display: flex; + gap: 8px; + align-items: center; +} + +.react-scan-header-right { + display: flex; + gap: 4px; + align-items: center; +} + +.react-scan-replay-button { + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.1); + border: none; + border-radius: 4px; + color: #fff; + cursor: pointer; + transition: all 150ms ease; + outline: none; +} + +.react-scan-replay-button:hover { + background: rgba(255, 255, 255, 0.15); +} + +.react-scan-component-name { + font-weight: 500; + color: #fff; +} + +.react-scan-metrics { + color: #888; + font-size: 12px; +} + + +.react-scan-section { + @apply py-2 px-4; + @apply bg-black text-[#888]; + @apply before:content-[attr(data-section)] before:text-gray-500; +} + +.react-scan-section:last-child { + margin-bottom: 0; +} + +.react-scan-property { + margin-left: 14px; + margin-top: 8px; + position: relative; +} + +.react-scan-section>.react-scan-property:first-child { + margin-top: 4px; +} + +.react-scan-key { + color: #fff; +} + +.react-scan-warning { + padding-right: 4px; +} + +.react-scan-string { + color: #9ECBFF; +} + +.react-scan-number { + color: #79C7FF; +} + +.react-scan-boolean { + color: #56B6C2; +} + +.react-scan-input { + background: #000; + border: none; + color: #fff; +} + +.react-scan-object-key { + color: #fff; +} + +.react-scan-array { + color: #fff; +} + +.react-scan-expandable { + display: flex; + align-items: flex-start; +} + +.react-scan-arrow { + cursor: pointer; + content: '▶'; + display: inline-block; + font-size: 8px; + margin: 5px 4px 0 0; + transition: transform 150ms ease; + width: 8px; + flex-shrink: 0; + color: #888; +} + +.react-scan-expanded>.react-scan-arrow { + transform: rotate(90deg); +} + +.react-scan-property-content { + flex: 1; + min-width: 0; +} + +.react-scan-hidden { + display: none; +} + +.react-scan-array-container { + overflow-y: auto; + margin-left: 14px; + margin-top: 8px; + border-left: 1px solid rgba(255, 255, 255, 0.1); + padding-left: 8px; +} + +.react-scan-nested-object { + margin-left: 14px; + margin-top: 8px; + border-left: 1px solid rgba(255, 255, 255, 0.1); + padding-left: 8px; +} + +.react-scan-nested-object>.react-scan-property { + margin-top: 8px; +} + +.react-scan-nested-object>.react-scan-property:first-child { + margin-top: 0; +} + +.react-scan-preview-line { + position: relative; + padding: 3px 6px; + border-radius: 4px; + font-family: 'Menlo', 'Monaco', 'Courier New', monospace; + display: flex; + align-items: center; +} + +.react-scan-flash-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(142, 97, 227, 1); + pointer-events: none; + opacity: 0; + z-index: 999999; + mix-blend-mode: multiply; + transition: opacity 150ms ease-in; + border-radius: 4px; +} + +.react-scan-flash-active { + opacity: 0.4; + transition: opacity 300ms ease-in-out; +} + +/* Hover states */ +#react-scan-toolbar button:hover { + background: rgba(255, 255, 255, 0.1); +} + +#react-scan-toolbar button:active { + background: rgba(255, 255, 255, 0.15); +} + +/* Focus states */ +#react-scan-toolbar button:focus-visible { + outline: 2px solid #0070F3; + outline-offset: -2px; +} + +/* Scrollbar styling */ +.react-scan-props::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +.react-scan-props::-webkit-scrollbar-track { + background: transparent; +} + +.react-scan-props::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; +} + +.react-scan-props::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.3); +} + +#react-scan-toolbar::-webkit-scrollbar { + width: 4px; + height: 4px; + +} + +#react-scan-toolbar::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; +} + +#react-scan-toolbar::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + border-radius: 4px; +} + +#react-scan-toolbar::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.4); +} + +/* For Firefox */ +#react-scan-toolbar * { + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.1); +} + +.nav-button { + opacity: var(--nav-opacity, 1); +} + +.react-scan-toolbar { + border: 1px solid blue; +} diff --git a/packages/scan/src/core/web/assets/svgs/svgs.ts b/packages/scan/src/core/web/assets/svgs/svgs.ts new file mode 100644 index 00000000..1c39a3ca --- /dev/null +++ b/packages/scan/src/core/web/assets/svgs/svgs.ts @@ -0,0 +1,77 @@ +export const ICONS = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; diff --git a/packages/scan/src/core/web/components/icon/index.tsx b/packages/scan/src/core/web/components/icon/index.tsx new file mode 100644 index 00000000..bcf08517 --- /dev/null +++ b/packages/scan/src/core/web/components/icon/index.tsx @@ -0,0 +1,50 @@ +import type { JSX } from 'preact'; +import { + type ForwardedRef, + forwardRef, +} from 'preact/compat'; + +export interface SVGIconProps { + size?: number | Array; + name: string; + fill?: string; + stroke?: string; + className?: string; + externalURL?: string; + style?: JSX.CSSProperties; +} + +export const Icon = forwardRef((props: SVGIconProps, ref: ForwardedRef) => { + const { + size = 15, + name, + fill = 'currentColor', + stroke = 'currentColor', + className, + externalURL = '', + style, + } = props; + + const width = Array.isArray(size) ? size[0] : size; + const height = Array.isArray(size) ? size[1] || size[0] : size; + + const attributes = { + width: `${width}px`, + height: `${height}px`, + fill, + stroke, + className, + style, + }; + + const path = `${externalURL}#${name}`; + + return ( + + + + ); +}); diff --git a/packages/scan/src/core/web/components/widget/constants.ts b/packages/scan/src/core/web/components/widget/constants.ts new file mode 100644 index 00000000..c522015a --- /dev/null +++ b/packages/scan/src/core/web/components/widget/constants.ts @@ -0,0 +1,28 @@ +export const LOCALSTORAGE_KEY = 'react-scan-widget'; + +export const SAFE_AREA = 20; +export const MIN_SIZE = { width: 360, height: 240 }; +export const MINIMIZED_SIZE = { width: 'min-content' } as const; +export const RESIZE_HANDLE_SIZE = 16; // 4rem from the Tailwind class + +export const CORNER_CONFIGS = { + 'top-left': { + position: { x: SAFE_AREA, y: SAFE_AREA }, + resize: { position: 'bottom-0 right-0 translate-x-1/2 translate-y-1/2', direction: 'bottom-right' } + }, + 'top-right': { + position: { x: (width: number) => window.innerWidth - width - SAFE_AREA, y: SAFE_AREA }, + resize: { position: 'bottom-0 left-0 -translate-x-1/2 translate-y-1/2', direction: 'bottom-left' } + }, + 'bottom-left': { + position: { x: SAFE_AREA, y: (height: number) => window.innerHeight - height - SAFE_AREA }, + resize: { position: 'top-0 right-0 translate-x-1/2 -translate-y-1/2', direction: 'top-right' } + }, + 'bottom-right': { + position: { + x: (width: number) => window.innerWidth - width - SAFE_AREA, + y: (height: number) => window.innerHeight - height - SAFE_AREA + }, + resize: { position: 'top-0 left-0 -translate-x-1/2 -translate-y-1/2', direction: 'top-left' } + } +} as const; diff --git a/packages/scan/src/core/web/components/widget/header.tsx b/packages/scan/src/core/web/components/widget/header.tsx new file mode 100644 index 00000000..245e71f2 --- /dev/null +++ b/packages/scan/src/core/web/components/widget/header.tsx @@ -0,0 +1,148 @@ +import { useRef, useEffect, useCallback, useState } from "preact/hooks"; +import { getDisplayName } from 'bippy'; +import { cn } from "@web-utils/helpers"; +import { Store } from "../../../.."; +import { getCompositeComponentFromElement, getOverrideMethods } from "../../inspect-element/utils"; +import { replayComponent } from "../../inspect-element/view-state"; +import { Icon } from "../icon"; + +export const Header = () => { + const inspectState = Store.inspectState.value; + const refComponentName = useRef(null); + const refMetrics = useRef(null); + const [isReplaying, setIsReplaying] = useState(false); + + useEffect(() => { + const updateMetrics = () => { + if (!refComponentName.current || !refMetrics.current) return; + if (inspectState.kind !== 'focused') return; + + if (!document.contains(inspectState.focusedDomElement)) { + if (Store.inspectState.value.propContainer) { + Store.inspectState.value = { + kind: 'inspect-off', + propContainer: Store.inspectState.value.propContainer, + }; + } + return; + } + + + const { parentCompositeFiber } = getCompositeComponentFromElement(inspectState.focusedDomElement); + + if (!parentCompositeFiber) return; + + const reportDataFiber = + Store.reportData.get(parentCompositeFiber) ?? + (parentCompositeFiber.alternate + ? Store.reportData.get(parentCompositeFiber.alternate) + : null); + + const componentName = getDisplayName(parentCompositeFiber.type) ?? 'Unknown'; + + const renderCount = reportDataFiber?.count ?? 0; + const renderTime = reportDataFiber?.time ?? 0; + + refComponentName.current.textContent = componentName; + refMetrics.current.dataset.text = renderCount > 0 + ? `${renderCount} renders${renderTime > 0 ? ` • ${renderTime.toFixed(2)}ms` : ''}` + : ''; + }; + + const unsubscribe = Store.lastReportTime.subscribe(updateMetrics); + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape' && inspectState.kind === 'focused') { + if (Store.inspectState.value.propContainer) { + Store.inspectState.value.propContainer.innerHTML = ''; + Store.inspectState.value = { + kind: 'inspecting', + hoveredDomElement: inspectState.focusedDomElement, + propContainer: Store.inspectState.value.propContainer, + }; + } + } + }; + + window.addEventListener('keydown', handleKeyDown, { capture: true }); + + return () => { + unsubscribe(); + window.removeEventListener('keydown', handleKeyDown, { capture: true }); + }; + }, [inspectState]); + + const handleClose = useCallback(() => { + if (Store.inspectState.value.propContainer) { + Store.inspectState.value = { + kind: 'inspect-off', + propContainer: Store.inspectState.value.propContainer, + }; + } + }, []); + + const handleReplay = useCallback((e: MouseEvent) => { + void (async () => { + e.stopPropagation(); + if (isReplaying || inspectState.kind !== 'focused') return; + + const { parentCompositeFiber } = getCompositeComponentFromElement(inspectState.focusedDomElement); + if (!parentCompositeFiber) return; + + const { overrideProps, overrideHookState } = getOverrideMethods(); + if (!overrideProps || !overrideHookState) return; + + setIsReplaying(true); + + try { + await replayComponent(parentCompositeFiber); + } finally { + setTimeout(() => { + setIsReplaying(false); + }, 300); + } + })(); + }, [inspectState, isReplaying]); + + if (inspectState.kind !== 'focused') { + return null; + } + + const { overrideProps } = getOverrideMethods(); + const canEdit = !!overrideProps; + + return ( +
+
+ + +
+
+ {canEdit && ( + + )} + +
+
+ ); +}; diff --git a/packages/scan/src/core/web/components/widget/helpers.ts b/packages/scan/src/core/web/components/widget/helpers.ts new file mode 100644 index 00000000..69c170a6 --- /dev/null +++ b/packages/scan/src/core/web/components/widget/helpers.ts @@ -0,0 +1,25 @@ +import { signal } from "@preact/signals"; +import { MIN_SIZE, SAFE_AREA } from "./constants"; +import { type WidgetState, type Corner, type Position } from "./types"; + +export const calculatePosition = (corner: Corner, width: number, height: number): Position => { + switch (corner) { + case 'top-right': + return { x: window.innerWidth - width - SAFE_AREA, y: SAFE_AREA }; + case 'bottom-right': + return { x: window.innerWidth - width - SAFE_AREA, y: window.innerHeight - height - SAFE_AREA }; + case 'bottom-left': + return { x: SAFE_AREA, y: window.innerHeight - height - SAFE_AREA }; + case 'top-left': + default: + return { x: SAFE_AREA, y: SAFE_AREA }; + } +}; + +export const signalWidgetState = signal({ + position: calculatePosition('top-left', 0, 0), + size: { width: 0, height: 0 }, + corner: 'top-left', + lastExpandedWidth: MIN_SIZE.width, + lastExpandedHeight: MIN_SIZE.height, +}); diff --git a/packages/scan/src/core/web/components/widget/index.tsx b/packages/scan/src/core/web/components/widget/index.tsx new file mode 100644 index 00000000..e09afa93 --- /dev/null +++ b/packages/scan/src/core/web/components/widget/index.tsx @@ -0,0 +1,443 @@ +import { type JSX } from 'preact'; +import { useRef, useCallback, useEffect } from 'preact/hooks'; +import { cn, readLocalStorage, saveLocalStorage } from '@web-utils/helpers'; +import { Store } from '../../../..'; +import { signalWidgetState, signalSelectedCorner } from '../../state'; +import { Header } from './header'; +import { type WidgetState, type Corner, type Position, type StoredWidgetState } from './types' +import { MIN_SIZE, SAFE_AREA, CORNER_CONFIGS, RESIZE_HANDLE_SIZE, LOCALSTORAGE_KEY } from './constants'; +import Toolbar from './toolbar'; +import { ResizeHandle } from './resize-handle'; +import { calculatePosition } from './helpers'; + +export const Widget = () => { + const inspectState = Store.inspectState; + + const isInspectFocused = inspectState.value.kind === 'focused'; + + + // Refs for all mutable state + const refContainer = useRef(null); + const refPropContainer = useRef(null); + const refFooter = useRef(null); + + // Add ref for footer height before state initialization + const refFooterHeight = useRef(0); + + // Measure footer height immediately + useEffect(() => { + if (!refFooter.current) return; + refFooterHeight.current = refFooter.current.offsetHeight; + }, []); + + // Initialize state from storage + useEffect(() => { + const stored = readLocalStorage(LOCALSTORAGE_KEY); + if (stored) { + signalWidgetState.value = { + ...signalWidgetState.value, + corner: stored.corner, + lastExpandedWidth: stored.size.width, + lastExpandedHeight: stored.size.height, + }; + } + }, []); + + const refDragStart = useRef(null); + const refInitialPosition = useRef(null); + + // Add this helper function at the top of the component + const getTransformOrigin = useCallback((corner: Corner) => { + switch (corner) { + case 'top-left': return 'top left'; + case 'top-right': return 'top right'; + case 'bottom-left': return 'bottom left'; + case 'bottom-right': return 'bottom right'; + default: return 'center'; + } + }, []); + + // Modify updateState to use calculatePosition + const updateState = useCallback((updates: Partial) => { + signalWidgetState.value = { ...signalWidgetState.value, ...updates }; + + if (!refContainer.current) return; + + requestAnimationFrame(() => { + if (!refContainer.current) return; + + const { corner } = signalWidgetState.value; + const width = signalWidgetState.value.size.width; + const height = isInspectFocused ? signalWidgetState.value.size.height : refFooterHeight.current; + + const position = calculatePosition(corner, width, height); + + refContainer.current.style.width = `${width}px`; + refContainer.current.style.height = `${height}px`; + refContainer.current.style.transform = `translate(${position.x}px, ${position.y}px)`; + refContainer.current.style.transformOrigin = getTransformOrigin(corner); + + signalWidgetState.value.position = position; + + if (isInspectFocused) { + saveLocalStorage(LOCALSTORAGE_KEY, { + corner, + size: { + width: signalWidgetState.value.lastExpandedWidth, + height: signalWidgetState.value.lastExpandedHeight + } + }); + } + }); + }, [getTransformOrigin]); + + // Move determineCorner before handleMouseDown + const determineCorner = useCallback((x: number, y: number): Corner => { + return `${y < window.innerHeight / 2 ? 'top' : 'bottom'}-${x < window.innerWidth / 2 ? 'left' : 'right'}` as Corner; + }, []); + + // Modified drag handler + const handleMouseDown = useCallback((event: JSX.TargetedMouseEvent) => { + if ((event.target as HTMLElement).closest('button')) { + return; + } + + if (!refContainer.current) return; + + // Remove transition when starting drag + refContainer.current.style.transition = 'none'; + + const rect = refContainer.current.getBoundingClientRect(); + const isClickInResizeArea = (() => { + const clickX = event.clientX - rect.left; + const clickY = event.clientY - rect.top; + + switch (signalWidgetState.value.corner) { + case 'top-left': + return ( + clickX >= rect.width - RESIZE_HANDLE_SIZE && + clickY >= rect.height - RESIZE_HANDLE_SIZE + ); + case 'top-right': + return ( + clickX <= RESIZE_HANDLE_SIZE && + clickY >= rect.height - RESIZE_HANDLE_SIZE + ); + case 'bottom-left': + return ( + clickX >= rect.width - RESIZE_HANDLE_SIZE && + clickY <= RESIZE_HANDLE_SIZE + ); + case 'bottom-right': + return ( + clickX <= RESIZE_HANDLE_SIZE && + clickY <= RESIZE_HANDLE_SIZE + ); + } + })(); + + // Don't trigger repositioning if click was in resize area + if (isClickInResizeArea) return; + + event.preventDefault(); + + refDragStart.current = { x: event.clientX, y: event.clientY }; + refInitialPosition.current = signalWidgetState.value.position; + + const handleMouseMove = (e: globalThis.MouseEvent) => { + if (!refDragStart.current || !refInitialPosition.current || !refContainer.current) return; + + const deltaX = e.clientX - refDragStart.current.x; + const deltaY = e.clientY - refDragStart.current.y; + + const newX = Math.min( + Math.max(SAFE_AREA, refInitialPosition.current.x + deltaX), + window.innerWidth - signalWidgetState.value.size.width - SAFE_AREA + ); + const newY = Math.min( + Math.max(SAFE_AREA, refInitialPosition.current.y + deltaY), + window.innerHeight - signalWidgetState.value.size.height - SAFE_AREA + ); + + refContainer.current.style.transform = `translate(${newX}px, ${newY}px)`; + signalWidgetState.value.position = { x: newX, y: newY }; + }; + + const handleMouseUp = (e: globalThis.MouseEvent) => { + if (!refDragStart.current || !refContainer.current) return; + + // Add transition before moving to corner + refContainer.current.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'; + + const newCorner = determineCorner(e.clientX, e.clientY); + const newPosition = calculatePosition(newCorner, + signalWidgetState.value.size.width, + signalWidgetState.value.size.height + ); + + // Update position with animation + refContainer.current.style.transform = `translate(${newPosition.x}px, ${newPosition.y}px)`; + + // Update state after animation + requestAnimationFrame(() => { + if (refContainer.current) { + updateState({ + corner: newCorner, + position: newPosition + }); + + saveLocalStorage(LOCALSTORAGE_KEY, { + corner: newCorner, + size: { + width: signalWidgetState.value.lastExpandedWidth, + height: signalWidgetState.value.lastExpandedHeight + } + }); + } + }); + + refDragStart.current = null; + refInitialPosition.current = null; + + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }; + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + }, [determineCorner, updateState]); + + // Window resize handler + useEffect(() => { + const handleWindowResize = () => { + const { corner, size, position } = signalWidgetState.value; + + // Get current window dimensions + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + // Calculate maximum allowed positions + const maxX = windowWidth - size.width - SAFE_AREA; + const maxY = windowHeight - size.height - SAFE_AREA; + + // Ensure widget stays within bounds and maintains corner position + let newX = position.x; + let newY = position.y; + + switch (corner) { + case 'top-left': + newX = SAFE_AREA; + newY = SAFE_AREA; + break; + case 'top-right': + newX = Math.min(maxX, windowWidth - size.width - SAFE_AREA); + newY = SAFE_AREA; + break; + case 'bottom-left': + newX = SAFE_AREA; + newY = Math.min(maxY, windowHeight - size.height - SAFE_AREA); + break; + case 'bottom-right': + newX = Math.min(maxX, windowWidth - size.width - SAFE_AREA); + newY = Math.min(maxY, windowHeight - size.height - SAFE_AREA); + break; + } + + // Update position if it changed + if (newX !== position.x || newY !== position.y) { + updateState({ position: { x: newX, y: newY } }); + } + + // Adjust size if it exceeds new window dimensions + const newSize = { + width: Math.min(size.width, windowWidth - (SAFE_AREA * 2)), + height: Math.min(size.height, windowHeight - (SAFE_AREA * 2)) + }; + + if (newSize.width !== size.width || newSize.height !== size.height) { + updateState({ size: newSize }); + } + }; + + window.addEventListener('resize', handleWindowResize); + return () => window.removeEventListener('resize', handleWindowResize); + }, [updateState]); + + // Add this effect right after the refs and state declarations + useEffect(() => { + if (!refContainer.current || !refFooter.current) { + return; + } + + // Ensure no transition during initial mount + refContainer.current.style.transition = 'none'; + + const { size } = signalWidgetState.value; + const height = isInspectFocused ? size.height : refFooter.current.clientHeight; + const width = isInspectFocused ? size.width : MIN_SIZE.width; + const position = calculatePosition(signalWidgetState.value.corner, width, refFooter.current.clientHeight); + + refContainer.current.style.width = `${width}px`; + refContainer.current.style.height = `${height}px`; + refContainer.current.style.transform = `translate(${position.x}px, ${position.y}px)`; + }, []); + + // Add refs for initial minimized dimensions + const refMinimizedWidth = useRef(0); + const refMinimizedHeight = useRef(0); + + // Measure and store initial dimensions on mount + useEffect(() => { + if (!refContainer.current || !refFooter.current) return; + + // Measure footer height + refMinimizedHeight.current = refFooter.current.offsetHeight; + + // Set width to min-content and measure + refContainer.current.style.width = 'min-content'; + refMinimizedWidth.current = refContainer.current.offsetWidth; + + // Set initial position with measured dimensions + const newPosition = calculatePosition( + signalWidgetState.value.corner, + refMinimizedWidth.current, + refMinimizedHeight.current + ); + + signalWidgetState.value.position = newPosition; + signalWidgetState.value.size = { + width: refMinimizedWidth.current, + height: refMinimizedHeight.current + }; + + refContainer.current.style.transform = `translate(${newPosition.x}px, ${newPosition.y}px)`; + }, []); + + useEffect(() => { + if (!refContainer.current) { + return; + } + + const newWidth = isInspectFocused ? signalWidgetState.value.lastExpandedWidth : refMinimizedWidth.current; + const newHeight = isInspectFocused ? signalWidgetState.value.lastExpandedHeight : refMinimizedHeight.current; + const newPosition = calculatePosition(signalWidgetState.value.corner, newWidth, newHeight); + + requestAnimationFrame(() => { + if (!refContainer.current) return; + + refContainer.current.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'; + refContainer.current.style.width = `${newWidth}px`; + refContainer.current.style.height = `${newHeight}px`; + refContainer.current.style.transform = `translate(${newPosition.x}px, ${newPosition.y}px)`; + + signalSelectedCorner.value = signalWidgetState.value.corner; + + signalWidgetState.value = { + ...signalWidgetState.value, + size: { width: newWidth, height: newHeight }, + position: newPosition, + }; + }); + }, [isInspectFocused]); + + return ( +
+
+
+
+
+

Widget Content

+

Scrollable content goes here...

+ {Array.from({ length: 10 }).map((_, i) => ( +

Scroll content {i + 1}

+ ))} +
+
+
+ +
+ +
+ + { + isInspectFocused && Object.entries(CORNER_CONFIGS).map(([key, config]) => + signalWidgetState.value.corner === key && ( + <> + {/* Horizontal line */} + + {/* Vertical line */} + + {/* Corner dot */} + + + ) + ) + } +
+ ); +}; diff --git a/packages/scan/src/core/web/components/widget/resize-handle.tsx b/packages/scan/src/core/web/components/widget/resize-handle.tsx new file mode 100644 index 00000000..4db0db43 --- /dev/null +++ b/packages/scan/src/core/web/components/widget/resize-handle.tsx @@ -0,0 +1,149 @@ +import { type RefObject, type JSX } from 'preact'; +import { useCallback } from "preact/hooks"; +import { cn, saveLocalStorage } from '@web-utils/helpers'; +import { signalWidgetState } from '../../state'; +import { LOCALSTORAGE_KEY, MIN_SIZE, SAFE_AREA } from './constants'; + +interface ResizeHandleProps { + refContainer: RefObject; + position: string; + direction: string; + isLine?: boolean; +} + +export const ResizeHandle = (props: ResizeHandleProps) => { + const { + refContainer, + position, + direction, + isLine = false + } = props; + + // Modified resize handler + const handleResize = useCallback((e: JSX.TargetedMouseEvent, direction: string) => { + if (!refContainer.current) return; + + refContainer.current.style.transition = 'none'; + + const handleMouseMove = (e: globalThis.MouseEvent) => { + if (!refContainer.current) return; + + const rect = refContainer.current.getBoundingClientRect(); + let newWidth = signalWidgetState.value.size.width; + let newHeight = signalWidgetState.value.size.height; + let newX = signalWidgetState.value.position.x; + let newY = signalWidgetState.value.position.y; + + // Calculate max dimensions (half of available space) + const maxWidth = Math.min((window.innerWidth - (SAFE_AREA * 2)) / 2); + const maxHeight = Math.min((window.innerHeight - (SAFE_AREA * 2)) / 2); + + if (direction.includes('right')) { + newWidth = Math.max( + MIN_SIZE.width, + Math.min(e.clientX - rect.left, maxWidth) + ); + } else if (direction.includes('left')) { + const rightEdge = rect.right; + newWidth = Math.max( + MIN_SIZE.width, + Math.min(rightEdge - e.clientX, maxWidth) + ); + newX = Math.max(SAFE_AREA, rightEdge - newWidth); + } + + if (direction.includes('bottom')) { + newHeight = Math.max( + MIN_SIZE.height, + Math.min(e.clientY - rect.top, maxHeight) + ); + } else if (direction.includes('top')) { + const bottomEdge = rect.bottom; + newHeight = Math.max( + MIN_SIZE.height, + Math.min(bottomEdge - e.clientY, maxHeight) + ); + newY = Math.max(SAFE_AREA, bottomEdge - newHeight); + } + + // Ensure we don't exceed viewport bounds + if ((newX) + (newWidth) > window.innerWidth - SAFE_AREA) { + newWidth = window.innerWidth - (newX) - SAFE_AREA; + } + if ((newY) + (newHeight) > window.innerHeight - SAFE_AREA) { + newHeight = window.innerHeight - (newY) - SAFE_AREA; + } + + // Only update DOM and ref state during move + refContainer.current.style.width = `${newWidth}px`; + refContainer.current.style.height = `${newHeight}px`; + refContainer.current.style.transform = `translate(${newX}px, ${newY}px)`; + + // Update ref state without storage + signalWidgetState.value.position = { x: newX, y: newY }; + signalWidgetState.value.size = { width: newWidth, height: newHeight }; + signalWidgetState.value.lastExpandedWidth = newWidth; + signalWidgetState.value.lastExpandedHeight = newHeight; + }; + + // Save only on mouseup + const handleMouseUp = () => { + if (!refContainer.current) return; + + // Store final dimensions + saveLocalStorage(LOCALSTORAGE_KEY, { + corner: signalWidgetState.value.corner, + size: { + width: signalWidgetState.value.lastExpandedWidth, + height: signalWidgetState.value.lastExpandedHeight + } + }); + + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }; + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + }, []); + + return ( +
{ + e.preventDefault(); + e.stopPropagation(); + handleResize(e, direction); + }} + /> + ); +}; diff --git a/packages/scan/src/core/web/components/widget/toolbar.tsx b/packages/scan/src/core/web/components/widget/toolbar.tsx new file mode 100644 index 00000000..19a00468 --- /dev/null +++ b/packages/scan/src/core/web/components/widget/toolbar.tsx @@ -0,0 +1,245 @@ +import { useCallback, useEffect, useMemo } from "preact/hooks"; +import { signal } from "@preact/signals"; +import { cn } from "@web-utils/helpers"; +import { ReactScanInternals, setOptions, Store } from "../../../.."; +import { INSPECT_TOGGLE_ID } from "../../inspect-element/inspect-state-machine"; +import { getNearestFiberFromElement } from "../../inspect-element/utils"; +import { Icon } from "../icon"; + +const isSoundOnSignal = signal(false); + +interface ToolbarProps { + refPropContainer: React.RefObject; +} + +export const Toolbar = ({ refPropContainer }: ToolbarProps) => { + const inspectState = Store.inspectState; + + const isInspectFocused = inspectState.value.kind === 'focused'; + const isInspectActive = inspectState.value.kind === 'inspecting'; + const isPaused = ReactScanInternals.instrumentation?.isPaused!; + + const { inspectIcon, inspectColor } = useMemo(() => { + let inspectIcon = null; + let inspectColor = '#999'; + + if (isInspectActive) { + inspectIcon = ; + inspectColor = 'rgba(142, 97, 227, 1)'; + } else if (isInspectFocused) { + inspectIcon = ; + inspectColor = 'rgba(142, 97, 227, 1)'; + } else { + inspectIcon = ; + inspectColor = '#999'; + } + + return { inspectIcon, inspectColor }; + }, [isInspectActive, isInspectFocused]); + + const onToggleInspect = useCallback(() => { + const currentState = Store.inspectState.value; + switch (currentState.kind) { + case 'inspecting': + Store.inspectState.value = { + kind: 'inspect-off', + propContainer: currentState.propContainer, + }; + break; + case 'focused': + Store.inspectState.value = { + kind: 'inspect-off', + propContainer: currentState.propContainer, + }; + break; + case 'inspect-off': + Store.inspectState.value = { + kind: 'inspecting', + hoveredDomElement: null, + propContainer: refPropContainer.current!, + }; + break; + case 'uninitialized': + break; + } + }, [Store.inspectState.value]); + + const onPreviousFocus = useCallback(() => { + const currentState = Store.inspectState.value; + if (currentState.kind !== 'focused' || !currentState.focusedDomElement) + return; + + const focusedDomElement = currentState.focusedDomElement; + const allElements = Array.from(document.querySelectorAll('*')).filter( + (el): el is HTMLElement => el instanceof HTMLElement, + ); + const currentIndex = allElements.indexOf(focusedDomElement); + if (currentIndex === -1) return; + + let prevElement: HTMLElement | null = null; + let prevIndex = currentIndex - 1; + const currentFiber = getNearestFiberFromElement(focusedDomElement); + + while (prevIndex >= 0) { + const fiber = getNearestFiberFromElement(allElements[prevIndex]); + if (fiber && fiber !== currentFiber) { + prevElement = allElements[prevIndex]; + break; + } + prevIndex--; + } + + if (prevElement) { + Store.inspectState.value = { + kind: 'focused', + focusedDomElement: prevElement, + propContainer: currentState.propContainer, + }; + } + }, [Store.inspectState.value]); + + const onNextFocus = useCallback(() => { + const currentState = Store.inspectState.value; + if (currentState.kind !== 'focused' || !currentState.focusedDomElement) + return; + + const focusedDomElement = currentState.focusedDomElement; + const allElements = Array.from(document.querySelectorAll('*')).filter( + (el): el is HTMLElement => el instanceof HTMLElement, + ); + const currentIndex = allElements.indexOf(focusedDomElement); + if (currentIndex === -1) return; + + let nextElement: HTMLElement | null = null; + let nextIndex = currentIndex + 1; + const prevFiber = getNearestFiberFromElement(focusedDomElement); + + while (nextIndex < allElements.length) { + const fiber = getNearestFiberFromElement(allElements[nextIndex]); + if (fiber && fiber !== prevFiber) { + nextElement = allElements[nextIndex]; + break; + } + nextIndex++; + } + + if (nextElement) { + Store.inspectState.value = { + kind: 'focused', + focusedDomElement: nextElement, + propContainer: currentState.propContainer, + }; + } + }, [Store.inspectState.value]); + + const onToggleActive = useCallback(() => { + isPaused.value = !isPaused.value; + }, []); + + const onSoundToggle = useCallback(() => { + isSoundOnSignal.value = !isSoundOnSignal.value; + setOptions({ playSound: isSoundOnSignal.value }); + }, [isSoundOnSignal.value]); + + useEffect(() => { + const currentState = Store.inspectState.value; + + if (currentState.kind === 'uninitialized') { + Store.inspectState.value = { + kind: 'inspect-off', + propContainer: refPropContainer.current!, + }; + } + }, []); + + return ( +
+ + + + +
+ { + isInspectFocused && ( +
+ + +
+ ) + } + + react-scan + +
+
+ ); +}; + +export default Toolbar; diff --git a/packages/scan/src/core/web/components/widget/types.ts b/packages/scan/src/core/web/components/widget/types.ts new file mode 100644 index 00000000..dd86035d --- /dev/null +++ b/packages/scan/src/core/web/components/widget/types.ts @@ -0,0 +1,29 @@ +export interface Position { + x: number; + y: number; +} + +export interface Size { + width: number; + height: number; +} + +export type Corner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; + +// For runtime state +export interface WidgetState { + position: Position; + size: Size; + corner: Corner; + lastExpandedWidth: number; + lastExpandedHeight: number; +} + +// For localStorage +export interface StoredWidgetState { + corner: Corner; + size: { + width: number; + height: number; + }; +} diff --git a/packages/scan/src/core/web/inspect-element/inspect-state-machine.ts b/packages/scan/src/core/web/inspect-element/inspect-state-machine.ts index 6cddf6cb..133e313a 100644 --- a/packages/scan/src/core/web/inspect-element/inspect-state-machine.ts +++ b/packages/scan/src/core/web/inspect-element/inspect-state-machine.ts @@ -1,7 +1,6 @@ import { didFiberRender } from 'bippy'; import { Store } from '../../index'; -import { throttle } from '../utils'; -import { restoreSizeFromLocalStorage } from '../toolbar'; +import { throttle } from '../utils/helpers'; import { renderPropsAndState } from './view-state'; import { currentLockIconRect, @@ -38,10 +37,11 @@ let animationId: ReturnType; type Kinds = States['kind']; -export const createInspectElementStateMachine = () => { +export const createInspectElementStateMachine = (shadow: ShadowRoot) => { if (typeof window === 'undefined') { return; } + let canvas = document.getElementById( INSPECT_OVERLAY_CANVAS_ID, ) as HTMLCanvasElement | null; @@ -58,7 +58,7 @@ export const createInspectElementStateMachine = () => { pointer-events: none; z-index: 214748367; `; - document.documentElement.appendChild(canvas); + shadow.appendChild(canvas); const ctx = canvas.getContext('2d', { alpha: true }); if (!ctx) { return; @@ -126,6 +126,7 @@ export const createInspectElementStateMachine = () => { clearCanvas(); updateCanvasSize(canvas, ctx); }; + window.addEventListener('mousemove', mouseMove, { capture: true }); return () => { @@ -199,7 +200,6 @@ export const createInspectElementStateMachine = () => { drawHoverOverlay(el as HTMLElement, canvas, ctx, 'locked'); - inspectState.propContainer.style.width = `${restoreSizeFromLocalStorage()}px`; Store.inspectState.value = { kind: 'focused', focusedDomElement: el as HTMLElement, @@ -228,7 +228,7 @@ export const createInspectElementStateMachine = () => { inspectState.hoveredDomElement, () => { drawHoverOverlay( - inspectState.hoveredDomElement!, + inspectState.hoveredDomElement, canvas, ctx, 'inspecting', @@ -263,9 +263,7 @@ export const createInspectElementStateMachine = () => { // potential race condition solution for some websites clearCanvas(); }, 500); - inspectState.propContainer.style.maxHeight = '0'; - inspectState.propContainer.style.width = 'fit-content'; - inspectState.propContainer.innerHTML = ''; + Store.inspectState.value = { kind: 'inspect-off', propContainer: inspectState.propContainer, @@ -278,27 +276,20 @@ export const createInspectElementStateMachine = () => { ctx, 'locked', ); + const element = inspectState.focusedDomElement; - const { parentCompositeFiber } = - getCompositeComponentFromElement(element); + const { parentCompositeFiber } = getCompositeComponentFromElement(element); + if (!parentCompositeFiber) { return; } - const reportDataFiber = - Store.reportData.get(parentCompositeFiber) ?? - (parentCompositeFiber.alternate - ? Store.reportData.get(parentCompositeFiber.alternate) - : null); - const didRender = didFiberRender(parentCompositeFiber); // because we react to any change, not just this fibers change, we need this check to know if the current fiber re-rendered for this publish renderPropsAndState( didRender, parentCompositeFiber, - reportDataFiber, - inspectState.propContainer, ); const keyDown = (e: KeyboardEvent) => { @@ -310,8 +301,7 @@ export const createInspectElementStateMachine = () => { ctx, 'inspecting', ); - inspectState.propContainer.style.maxHeight = '0'; - inspectState.propContainer.style.width = 'fit-content'; + inspectState.propContainer.innerHTML = ''; Store.inspectState.value = { kind: 'inspecting', @@ -343,7 +333,6 @@ export const createInspectElementStateMachine = () => { adjustedY <= currentLockIconRect.y + currentLockIconRect.height ) { inspectState.propContainer.innerHTML = ''; - inspectState.propContainer.style.maxHeight = '0'; clearCanvas(); drawHoverOverlay( @@ -362,6 +351,7 @@ export const createInspectElementStateMachine = () => { return; } }; + window.addEventListener('pointerdown', onpointerdownCanvasLockIcon, { capture: true, }); diff --git a/packages/scan/src/core/web/inspect-element/overlay.ts b/packages/scan/src/core/web/inspect-element/overlay.ts index 3825a45c..668e221b 100644 --- a/packages/scan/src/core/web/inspect-element/overlay.ts +++ b/packages/scan/src/core/web/inspect-element/overlay.ts @@ -34,13 +34,17 @@ const linearInterpolation = (start: number, end: number, t: number) => { }; export const drawHoverOverlay = ( - overlayElement: HTMLElement, - canvas: HTMLCanvasElement, - ctx: CanvasRenderingContext2D, + overlayElement: HTMLElement | null, + canvas: HTMLCanvasElement | null, + ctx: CanvasRenderingContext2D | null, kind: 'locked' | 'inspecting', ) => { - const { parentCompositeFiber, targetRect } = - getCompositeComponentFromElement(overlayElement); + if (!overlayElement || !canvas || !ctx) { + return; + } + + const { parentCompositeFiber, targetRect } = getCompositeComponentFromElement(overlayElement); + if (!parentCompositeFiber || !targetRect) { return; } diff --git a/packages/scan/src/core/web/inspect-element/utils.ts b/packages/scan/src/core/web/inspect-element/utils.ts index 260528b9..4c4b688e 100644 --- a/packages/scan/src/core/web/inspect-element/utils.ts +++ b/packages/scan/src/core/web/inspect-element/utils.ts @@ -10,7 +10,12 @@ import { isCompositeFiber, } from 'bippy'; import { ReactScanInternals, Store } from '../../index'; -import { getRect } from '../outline'; +import { getRect } from '../utils/outline'; + +interface OverrideMethods { + overrideProps: ((fiber: Fiber, path: Array, value: any) => void) | null; + overrideHookState: ((fiber: Fiber, id: string, path: Array, value: any) => void) | null; +} export const getFiberFromElement = (element: Element): Fiber | null => { if ('__REACT_DEVTOOLS_GLOBAL_HOOK__' in window) { @@ -284,7 +289,7 @@ export const hasValidParent = () => { return hasValidParent; }; -export const getOverrideMethods = () => { +export const getOverrideMethods = (): OverrideMethods => { let overrideProps = null; let overrideHookState = null; if ('__REACT_DEVTOOLS_GLOBAL_HOOK__' in window) { @@ -317,5 +322,6 @@ export const getOverrideMethods = () => { } } } + return { overrideProps, overrideHookState }; }; diff --git a/packages/scan/src/core/web/inspect-element/view-state.ts b/packages/scan/src/core/web/inspect-element/view-state.ts index 4f77bfa0..4a40397c 100644 --- a/packages/scan/src/core/web/inspect-element/view-state.ts +++ b/packages/scan/src/core/web/inspect-element/view-state.ts @@ -10,18 +10,16 @@ import { const EXPANDED_PATHS = new Set(); const fadeOutTimers = new WeakMap>(); -const disabledButtons = new Set(); export const renderPropsAndState = ( didRender: boolean, fiber: any, - reportDataFiber: any, - propsContainer: HTMLDivElement, ) => { - const { overrideProps } = getOverrideMethods(); - const canEdit = !!overrideProps; + const propContainer = Store.inspectState.value.propContainer; - const scrollTop = propsContainer.scrollTop; + if (!propContainer) { + return; + } const fiberContext = tryOrElse( () => Array.from(getAllFiberContexts(fiber).entries()).map((x) => x[1]), @@ -33,151 +31,13 @@ export const renderPropsAndState = ( const props = fiber.memoizedProps || {}; const state = getStateFromFiber(fiber) || {}; - const renderCount = reportDataFiber?.count || 0; - const renderTime = reportDataFiber?.time?.toFixed(2) || '0'; - const changedProps = new Set(getChangedProps(fiber)); const changedState = new Set(getChangedState(fiber)); - propsContainer.innerHTML = ''; + propContainer.innerHTML = ''; const inspector = document.createElement('div'); inspector.className = 'react-scan-inspector'; - const header = document.createElement('div'); - header.className = 'react-scan-header'; - header.innerHTML = ` -
- ${componentName} - - ${renderCount > 0 ? `${renderCount} renders` : ''} - ${renderCount > 0 && renderTime > 0 ? ' • ' : ''} - ${renderTime > 0 ? `${renderTime}ms` : ''} - -
-
- ${ - canEdit - ? ` - - ` - : '' - } - -
- `; - inspector.appendChild(header); - - const closeButton = header.querySelector( - '.react-scan-close-button', - )!; - closeButton.addEventListener('click', (e) => { - e.stopPropagation(); - const currentState = Store.inspectState.value; - if (currentState.kind !== 'focused') return; - - propsContainer.style.maxHeight = '0'; - propsContainer.style.width = 'fit-content'; - propsContainer.innerHTML = ''; - - Store.inspectState.value = { - kind: 'inspect-off', - propContainer: currentState.propContainer, - }; - }); - - if (canEdit) { - const replayButton = header.querySelector( - '.react-scan-replay-button', - )!; - - if (disabledButtons.has(replayButton)) { - replayButton.classList.add('disabled'); - } - - replayButton.addEventListener('click', (e: MouseEvent) => { - e.stopPropagation(); - if (disabledButtons.has(replayButton)) return; - - const { overrideProps, overrideHookState } = getOverrideMethods(); - if (!overrideProps || !overrideHookState) return; - - disabledButtons.add(replayButton); - replayButton.classList.add('disabled'); - - void (async () => { - try { - await replayComponent(fiber); - } finally { - setTimeout(() => { - disabledButtons.delete(replayButton); - replayButton.classList.remove('disabled'); - }, 300); - } - })(); - }); - } - - const styleElement = document.createElement('style'); - styleElement.textContent = ` - .react-scan-header-right { - display: flex; - gap: 4px; - } - .react-scan-replay-button, - .react-scan-close-button { - display: flex; - align-items: center; - padding: 4px; - border: none; - border-radius: 4px; - color: #fff; - cursor: pointer; - transition: opacity 150ms ease; - position: relative; - overflow: hidden; - isolation: isolate; - } - .react-scan-close-button { - background: rgba(255, 255, 255, 0.01); - } - .react-scan-close-button:hover { - background: rgba(255, 255, 255, 0.15); - } - .react-scan-replay-button { - background: rgba(142, 97, 227, 0.5) !important; - } - .react-scan-replay-button.disabled { - opacity: 0.5; - pointer-events: none; - } - .react-scan-replay-button:hover { - background: rgba(142, 97, 227, 0.25); - } - .react-scan-replay-button::before { - content: ''; - position: absolute; - inset: 0; - transform: translateX(-100%); - animation: shimmer 2s infinite; - background: linear-gradient( - to right, - transparent, - rgba(142, 97, 227, 0.3), - transparent - ); - } - @keyframes shimmer { - 100% { - transform: translateX(100%); - } - } - `; - document.head.appendChild(styleElement); - const content = document.createElement('div'); content.className = 'react-scan-content'; @@ -190,7 +50,7 @@ export const renderPropsAndState = ( componentName, didRender, fiber, - propsContainer, + propContainer, 'Props', props, changedProps, @@ -242,7 +102,7 @@ export const renderPropsAndState = ( componentName, didRender, fiber, - propsContainer, + propContainer, 'Context', contextObj, changedKeys, @@ -272,7 +132,7 @@ export const renderPropsAndState = ( componentName, didRender, fiber, - propsContainer, + propContainer, 'State', stateObj, changedState, @@ -291,13 +151,8 @@ export const renderPropsAndState = ( sections.forEach((section) => content.appendChild(section.element)); inspector.appendChild(content); - propsContainer.appendChild(inspector); - requestAnimationFrame(() => { - const contentHeight = inspector.getBoundingClientRect().height; - propsContainer.style.maxHeight = `${contentHeight}px`; - propsContainer.scrollTop = scrollTop; - }); + propContainer.appendChild(inspector); }; const lastChangedAt = new Map(); @@ -311,9 +166,10 @@ const renderSection = ( data: any, changedKeys: Set = new Set(), ) => { + const section = document.createElement('div'); section.className = 'react-scan-section'; - section.textContent = title; + section.dataset.section = title; const entries = Object.entries(data).sort(([keyA], [keyB]) => { const pathA = getPath(componentName, title.toLowerCase(), '', keyA); @@ -456,11 +312,14 @@ export const createPropertyElement = ( preview.className = 'react-scan-preview-line'; preview.dataset.key = key; preview.dataset.section = section; + + preview.innerHTML = ` + ${isBadRender ? '⚠️' : ''} ${key}: ${getValuePreview(value)} + )} react-scan-value with-data-text" data-text='${getValuePreview(value)}'> `; const content = document.createElement('div'); @@ -581,14 +440,6 @@ export const createPropertyElement = ( container.classList.remove('react-scan-expanded'); content.classList.add('react-scan-hidden'); } - - requestAnimationFrame(() => { - const inspector = propsContainer.firstElementChild as HTMLElement; - if (inspector) { - const contentHeight = inspector.getBoundingClientRect().height; - propsContainer.style.maxHeight = `${contentHeight}px`; - } - }); }); } else { const preview = document.createElement('div'); @@ -600,7 +451,7 @@ export const createPropertyElement = ( ${isBadRender ? '⚠️' : ''} ${key}: ${getValuePreview(value)} + )} react-scan-value with-data-text" data-text='${getValuePreview(value)}'> `; container.appendChild(preview); @@ -629,7 +480,7 @@ export const createPropertyElement = ( const updateValue = () => { const newValue = input.value; value = typeof value === 'number' ? Number(newValue) : newValue; - valueElement.textContent = getValuePreview(value); + (valueElement as HTMLElement).dataset.text = getValuePreview(value); tryOrElse(() => { input.replaceWith(valueElement); @@ -731,7 +582,7 @@ export const getValuePreview = (value: any) => { if (value === undefined) return 'undefined'; switch (typeof value) { case 'string': - return `"${value}"`; + return `"${value}"`; case 'number': return value.toString(); case 'boolean': @@ -748,7 +599,7 @@ export const getValuePreview = (value: any) => { } }; -const replayComponent = async (fiber: any) => { +export const replayComponent = async (fiber: any) => { try { const { overrideProps, overrideHookState } = getOverrideMethods(); if (!overrideProps || !overrideHookState || !fiber) return; diff --git a/packages/scan/src/core/web/overlay.ts b/packages/scan/src/core/web/overlay.ts index 6f89c939..d17871a2 100644 --- a/packages/scan/src/core/web/overlay.ts +++ b/packages/scan/src/core/web/overlay.ts @@ -1,78 +1,63 @@ -import { recalcOutlines } from './outline'; +import { recalcOutlines } from './utils/outline'; export const initReactScanOverlay = () => { - class ReactScanOverlay extends HTMLElement { - canvas: HTMLCanvasElement; - // @ts-expect-error will be defined - ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; + // Get the shadow root from our container + const container = document.getElementById('react-scan-root'); + const shadow = container?.shadowRoot; - constructor() { - super(); - - const shadow = this.attachShadow({ mode: 'open' }); - this.canvas = document.createElement('canvas'); - this.setupCanvas(); - - shadow.appendChild(this.canvas); - } - - public getContext() { - return this.ctx; - } - - setupCanvas() { - this.canvas.id = 'react-scan-canvas'; - this.canvas.style.position = 'fixed'; - this.canvas.style.top = '0'; - this.canvas.style.left = '0'; - this.canvas.style.width = '100vw'; - this.canvas.style.height = '100vh'; - this.canvas.style.pointerEvents = 'none'; - this.canvas.style.zIndex = '2147483646'; - this.canvas.setAttribute('aria-hidden', 'true'); - - const isOffscreenCanvasSupported = 'OffscreenCanvas' in globalThis; - const offscreenCanvas = isOffscreenCanvasSupported - ? this.canvas.transferControlToOffscreen() - : this.canvas; - - this.ctx = offscreenCanvas.getContext('2d') as - | OffscreenCanvasRenderingContext2D - | CanvasRenderingContext2D; - - let resizeScheduled = false; - - const resize = () => { - const dpi = window.devicePixelRatio || 1; - this.ctx.canvas.width = dpi * window.innerWidth; - this.ctx.canvas.height = dpi * window.innerHeight; - this.canvas.style.width = `${window.innerWidth}px`; - this.canvas.style.height = `${window.innerHeight}px`; - - this.ctx.resetTransform(); - this.ctx.scale(dpi, dpi); - - resizeScheduled = false; - }; - - resize(); + if (!shadow) { + return null; + } - window.addEventListener('resize', () => { - recalcOutlines(); - if (!resizeScheduled) { - resizeScheduled = true; - requestAnimationFrame(() => { - resize(); - }); - } - }); - window.addEventListener('scroll', () => { - recalcOutlines(); + const overlayElement = document.createElement('canvas'); + overlayElement.id = 'react-scan-overlay'; + + // Add the original styling + overlayElement.style.position = 'fixed'; + overlayElement.style.top = '0'; + overlayElement.style.left = '0'; + overlayElement.style.width = '100vw'; + overlayElement.style.height = '100vh'; + overlayElement.style.pointerEvents = 'none'; + overlayElement.style.zIndex = '2147483646'; + overlayElement.setAttribute('aria-hidden', 'true'); + + shadow.appendChild(overlayElement); + + const ctx = overlayElement.getContext('2d'); + if (!ctx) return null; + + let resizeScheduled = false; + + const updateCanvasSize = () => { + const dpi = window.devicePixelRatio || 1; + overlayElement.width = dpi * window.innerWidth; + overlayElement.height = dpi * window.innerHeight; + overlayElement.style.width = `${window.innerWidth}px`; + overlayElement.style.height = `${window.innerHeight}px`; + + ctx.resetTransform(); + ctx.scale(dpi, dpi); + + resizeScheduled = false; + }; + + window.addEventListener('resize', () => { + recalcOutlines(); + if (!resizeScheduled) { + resizeScheduled = true; + requestAnimationFrame(() => { + updateCanvasSize(); }); } - } + }); + + window.addEventListener('scroll', () => { + recalcOutlines(); + }); - customElements.define('react-scan-overlay', ReactScanOverlay); + // Initial size setup + updateCanvasSize(); - return ReactScanOverlay; + return ctx; }; diff --git a/packages/scan/src/core/web/state.ts b/packages/scan/src/core/web/state.ts new file mode 100644 index 00000000..45c74298 --- /dev/null +++ b/packages/scan/src/core/web/state.ts @@ -0,0 +1,14 @@ +import { signal } from '@preact/signals'; +import { type Corner, type WidgetState } from './components/widget/types'; +import { MIN_SIZE } from './components/widget/constants'; +import { calculatePosition } from './components/widget/helpers'; + +export const signalWidgetState = signal({ + position: calculatePosition('top-left', 0, 0), + size: { width: 0, height: 0 }, + corner: 'top-left', + lastExpandedWidth: MIN_SIZE.width, + lastExpandedHeight: MIN_SIZE.height, +}); + +export const signalSelectedCorner = signal(null); diff --git a/packages/scan/src/core/web/toolbar.tsx b/packages/scan/src/core/web/toolbar.tsx index 0aa8f852..8dc7b1b6 100644 --- a/packages/scan/src/core/web/toolbar.tsx +++ b/packages/scan/src/core/web/toolbar.tsx @@ -1,34 +1,46 @@ -import { useEffect, useRef, useState } from 'preact/hooks'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'; import { signal, useSignalEffect, type Signal } from '@preact/signals'; import { render } from 'preact'; +import { cn, throttle } from '@web-utils/helpers'; import { ReactScanInternals, setOptions, Store } from '../../index'; -import { throttle } from './utils'; -import { MONO_FONT } from './outline'; import { INSPECT_TOGGLE_ID, type States, } from './inspect-element/inspect-state-machine'; import { getNearestFiberFromElement } from './inspect-element/utils'; +import { Icon } from './components/icon'; +import { Widget } from './components/widget'; +import { Header } from './components/widget/header'; const isSoundOnSignal = signal(false); // Sizing and positioning signals +const CORNER_KEY = 'react-scan-toolbar-corner'; +type Corner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; +const DEFAULT_CORNER: Corner = 'top-left'; // Default is top-left + +// Function to save corner position +const saveCornerPosition = (corner: Corner) => { + localStorage.setItem(CORNER_KEY, corner); +}; + +// Update initial position signals const toolbarX = signal( parseInt( typeof window !== 'undefined' - ? (localStorage.getItem('react-scan-toolbar-x') ?? - String(window.innerWidth - 400)) + ? localStorage.getItem('react-scan-toolbar-x') ?? '0' : '0', ), ); + const toolbarY = signal( parseInt( typeof window !== 'undefined' - ? (localStorage.getItem('react-scan-toolbar-y') ?? - String(window.innerHeight - 500)) + ? localStorage.getItem('react-scan-toolbar-y') ?? '0' : '0', ), ); + const isDragging = signal(false); const isResizing = signal(false); @@ -41,6 +53,12 @@ const dragInitialXOffsetRef = { current: 0 }; const dragInitialYOffsetRef = { current: 0 }; const defaultWidth = 360; +const MIN_WIDTH = 360; +const MAX_WIDTH_RATIO = 0.5; +const EDGE_PADDING = 15; +const ANIMATION_DURATION = 300; // ms +const TRANSITION_TIMING = 'cubic-bezier(0.4, 0, 0.2, 1)'; + const persistSizeToLocalStorage = throttle((width: number) => { localStorage.setItem('react-scan-toolbar-width', String(width)); }, 100); @@ -50,154 +68,34 @@ export const restoreSizeFromLocalStorage = (): number => { return width ? parseInt(width, 10) : defaultWidth; }; -const PlaySVG = ( - - - - - - -); - -const PauseSVG = ( - - - - -); - -const InspectingSVG = ( - - - - - - - - - - - - -); - -const FocusingSVG = ( - - - - -); - -const NextSVG = ( - - - -); - -const PreviousSVG = ( - - - -); - -const SoundOnSVG = ( - - - - - -); - -const SoundOffSVG = ( - - - - - -); - -const EDGE_PADDING = 15; -const ANIMATION_DURATION = 300; // ms - const persistPositionToLocalStorage = throttle((x: number, y: number) => { localStorage.setItem('react-scan-toolbar-x', String(x)); localStorage.setItem('react-scan-toolbar-y', String(y)); }, 100); +// Ensure width stays within bounds and handle edge cases +const getConstrainedWidth = (width: number, maxWidth?: number | null): number => { + // Base width with border adjustment + const adjustedWidth = width - 2; // 2px for borders + + // Calculate max allowed width based on window or parent + const maxAllowedWidth = (() => { + // If valid maxWidth is provided (from parent), use it with padding + if (typeof maxWidth === 'number' && maxWidth > 0) { + return maxWidth - (2 * EDGE_PADDING); + } + + // Fallback to window width with ratio and padding + return (window.innerWidth * MAX_WIDTH_RATIO) - (2 * EDGE_PADDING); + })(); + + // Ensure width is between MIN_WIDTH and maxAllowedWidth + return Math.max( + MIN_WIDTH, + Math.min(adjustedWidth, maxAllowedWidth) + ); +}; + // Update props interface to make isPaused optional interface ToolbarProps { inspectState: Signal; @@ -219,10 +117,15 @@ export const Toolbar = ({ isDragging, isResizing, }: ToolbarProps) => { + const refTimer = useRef(); + + const refToolbarContent = useRef(null); + const refToolbarContentInitialWidth = useRef(); + const refPropContainer = useRef(null); + const refResizeHandle = useRef(null); + const refToolbar = useRef(null); + const [width, setWidth] = useState(restoreSizeFromLocalStorage); - const propContainerRef = useRef(null); - const resizeHandleRef = useRef(null); - const toolbarRef = useRef(null); const focusActive = inspectState.value.kind === 'focused'; const isInspectActive = inspectState.value.kind === 'inspecting'; @@ -231,67 +134,164 @@ export const Toolbar = ({ localStorage.setItem('react-scan-paused', String(!isPaused?.value)); }, [isPaused?.value]); - const ensureToolbarInBounds = () => { - if (!toolbarRef.current) return; - const toolbarRect = toolbarRef.current.getBoundingClientRect(); + useEffect(() => { + if (refToolbarContent.current && refPropContainer.current) { + const maxWidth = getConstrainedWidth(width, refPropContainer.current.parentElement?.clientWidth); + refToolbarContent.current.style.maxHeight = focusActive ? '50vh' : `39px`; + refToolbarContent.current.style.maxWidth = `${maxWidth}px`; + refPropContainer.current.style.minWidth = focusActive ? `${maxWidth - 2}px` : '100%'; + } + }, [focusActive]); + + // Add a ref to track if initial position is set + const isInitialPositionSet = useRef(false); + + // Add a single useEffect for position handling + useEffect(() => { + if (!refToolbar.current || isInitialPositionSet.current) return; + + // Get saved corner + const savedCorner = localStorage.getItem(CORNER_KEY) as Corner; + const rect = refToolbar.current.getBoundingClientRect(); + + // Calculate position based on saved corner or default + let newX, newY; + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + + switch (savedCorner || DEFAULT_CORNER) { + case 'top-left': + newX = EDGE_PADDING; + newY = EDGE_PADDING; + break; + case 'top-right': + newX = viewportWidth - rect.width - EDGE_PADDING; + newY = EDGE_PADDING; + break; + case 'bottom-left': + newX = EDGE_PADDING; + newY = viewportHeight - rect.height - EDGE_PADDING; + break; + case 'bottom-right': + newX = viewportWidth - rect.width - EDGE_PADDING; + newY = viewportHeight - rect.height - EDGE_PADDING; + break; + } + + // Set position + x.value = newX; + y.value = newY; + refToolbar.current.style.transform = `translate(${newX}px, ${newY}px)`; + persistPositionToLocalStorage(newX, newY); + + isInitialPositionSet.current = true; + + refToolbar.current?.classList.add('animate-fade-in', 'animate-duration-300', 'animate-delay-300'); + }, []); + + // Only save corner in ensureToolbarInBounds when actually dragging + const ensureToolbarInBounds = useCallback(() => { + if (!refToolbar.current) return; + + const toolbarRect = refToolbar.current.getBoundingClientRect(); const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; - // Snap to nearest horizontal edge + // Calculate distances to edges const distanceToLeft = toolbarRect.left; const distanceToRight = viewportWidth - toolbarRect.right; - const newX = - distanceToLeft <= distanceToRight - ? EDGE_PADDING - : viewportWidth - toolbarRect.width - EDGE_PADDING; - - // Snap to nearest vertical edge (optional) const distanceToTop = toolbarRect.top; const distanceToBottom = viewportHeight - toolbarRect.bottom; - const newY = - distanceToTop <= distanceToBottom - ? EDGE_PADDING - : viewportHeight - toolbarRect.height - EDGE_PADDING; + + // Determine corner based on closest edges + let corner: Corner; + if (distanceToTop <= distanceToBottom) { + corner = distanceToLeft <= distanceToRight ? 'top-left' : 'top-right'; + } else { + corner = distanceToLeft <= distanceToRight ? 'bottom-left' : 'bottom-right'; + } + + saveCornerPosition(corner); + + // Calculate new position based on corner + let newX, newY; + switch (corner) { + case 'top-left': + newX = EDGE_PADDING; + newY = EDGE_PADDING; + break; + case 'top-right': + newX = viewportWidth - toolbarRect.width - EDGE_PADDING; + newY = EDGE_PADDING; + break; + case 'bottom-left': + newX = EDGE_PADDING; + newY = viewportHeight - toolbarRect.height - EDGE_PADDING; + break; + case 'bottom-right': + newX = viewportWidth - toolbarRect.width - EDGE_PADDING; + newY = viewportHeight - toolbarRect.height - EDGE_PADDING; + break; + } x.value = newX; y.value = newY; persistPositionToLocalStorage(newX, newY); - toolbarRef.current.style.transition = `transform ${ANIMATION_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1)`; - toolbarRef.current.style.transform = `translate(${newX}px, ${newY}px)`; - setTimeout(() => { - if (toolbarRef.current) { - toolbarRef.current.style.transition = ''; + // Smoother transition + refToolbar.current.style.transition = `transform ${ANIMATION_DURATION}ms ${TRANSITION_TIMING}`; + refToolbar.current.style.transform = `translate(${newX}px, ${newY}px)`; + refTimer.current = setTimeout(() => { + if (refToolbar.current) { + refToolbar.current.style.transition = ''; } }, ANIMATION_DURATION); - }; - - const handleViewportChange = throttle(() => { - if (!isDragging.value && !isResizing.value) { - ensureToolbarInBounds(); - } - }, 100); + }, [isDragging.value]); useEffect(() => { + refToolbarContentInitialWidth.current = refToolbarContent.current?.offsetWidth ?? 0; + const handleViewportChange = throttle(() => { + if (!isDragging.value && !isResizing.value) { + ensureToolbarInBounds(); + } + }, 100); + + handleViewportChange(); + window.addEventListener('resize', handleViewportChange); window.addEventListener('scroll', handleViewportChange); + return () => { window.removeEventListener('resize', handleViewportChange); window.removeEventListener('scroll', handleViewportChange); }; }, []); - handleViewportChange(); // Mouse events for resizing useEffect(() => { const onMouseMove = (e: MouseEvent) => { - if (isResizing.value) { - const w = - initialWidthRef.current - (e.clientX - initialMouseXRef.current); - const newWidth = Math.max(360, w); - setWidth(newWidth); - persistSizeToLocalStorage(newWidth); + clearTimeout(refTimer.current); + if ( + isResizing.value + && refToolbarContent.current + && refToolbar.current + && refPropContainer.current + ) { + const w = initialWidthRef.current - (e.clientX - initialMouseXRef.current); + + // Calculate max width with padding consideration + const maxWidth = (window.innerWidth * MAX_WIDTH_RATIO) - (2 * EDGE_PADDING); + const newWidth = Math.min(maxWidth, Math.max(MIN_WIDTH, w)); + + refToolbarContent.current.style.maxWidth = `${newWidth}px`; + refPropContainer.current.style.minWidth = focusActive ? `${newWidth - 2}px` : '100%'; + + + refTimer.current = setTimeout(() => { + setWidth(newWidth); + persistSizeToLocalStorage(newWidth); + }, 100); } }; @@ -311,24 +311,25 @@ export const Toolbar = ({ document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); }; - }, [isDragging.value, isResizing.value]); + }, [isResizing.value]); const onToggleActive = () => { isPaused.value = !isPaused.value; }; + // pivanov useEffect(() => { const currentState = Store.inspectState.value; if (currentState.kind === 'uninitialized') { Store.inspectState.value = { kind: 'inspect-off', - propContainer: propContainerRef.current!, + propContainer: refPropContainer.current!, }; } }, []); - const onToggleInspect = () => { + const onToggleInspect = useCallback(() => { const currentState = Store.inspectState.value; switch (currentState.kind) { case 'inspecting': @@ -347,20 +348,20 @@ export const Toolbar = ({ Store.inspectState.value = { kind: 'inspecting', hoveredDomElement: null, - propContainer: propContainerRef.current!, + propContainer: refPropContainer.current!, }; break; case 'uninitialized': break; } - }; + }, [Store.inspectState.value]); - const onSoundToggle = () => { + const onSoundToggle = useCallback(() => { isSoundOnSignal.value = !isSoundOnSignal.value; setOptions({ playSound: isSoundOnSignal.value }); - }; + }, [isSoundOnSignal.value]); - const onNextFocus = () => { + const onNextFocus = useCallback(() => { const currentState = Store.inspectState.value; if (currentState.kind !== 'focused' || !currentState.focusedDomElement) return; @@ -392,9 +393,9 @@ export const Toolbar = ({ propContainer: currentState.propContainer, }; } - }; + }, [Store.inspectState.value]); - const onPreviousFocus = () => { + const onPreviousFocus = useCallback(() => { const currentState = Store.inspectState.value; if (currentState.kind !== 'focused' || !currentState.focusedDomElement) return; @@ -426,61 +427,67 @@ export const Toolbar = ({ propContainer: currentState.propContainer, }; } - }; + }, [Store.inspectState.value]); + + const { inspectIcon, inspectColor } = useMemo(() => { let inspectIcon = null; let inspectColor = '#999'; if (isInspectActive) { - inspectIcon = InspectingSVG; + inspectIcon = ; inspectColor = 'rgba(142, 97, 227, 1)'; } else if (focusActive) { - inspectIcon = FocusingSVG; + inspectIcon = ; inspectColor = 'rgba(142, 97, 227, 1)'; } else { - inspectIcon = InspectingSVG; + inspectIcon = ; inspectColor = '#999'; } - const propsMaxHeight = focusActive ? '450px' : '0'; - const propsContainerWidth = focusActive ? `${width}px` : '0'; + return { inspectIcon, inspectColor }; + }, [isInspectActive, focusActive]); - const showNavButtons = focusActive; + const onMouseDownToolbar = useCallback((e: MouseEvent) => { + e.preventDefault(); - const onMouseDownToolbar = (e: MouseEvent) => { const target = e.target as HTMLElement; - if (target.closest('button') ?? target === resizeHandleRef.current) { + if (target.closest('button') ?? target === refResizeHandle.current) { return; } + isDragging.value = true; dragInitialXOffsetRef.current = e.clientX - x.value; dragInitialYOffsetRef.current = e.clientY - y.value; - toolbarRef.current!.style.transition = 'none'; - e.preventDefault(); - }; - const onMouseDownResize = (e: MouseEvent) => { + // Remove transition during drag for immediate response + if (refToolbar.current) { + refToolbar.current.style.transition = 'none'; + } + }, [x, y, refToolbar, refResizeHandle]); + + const onMouseDownResize = useCallback((e: MouseEvent) => { + e.preventDefault(); isResizing.value = true; - initialWidthRef.current = propContainerRef.current!.offsetWidth; + initialWidthRef.current = refPropContainer.current!.offsetWidth; initialMouseXRef.current = e.clientX; - e.preventDefault(); - }; + }, []); useEffect(() => { - if (toolbarRef.current) { - toolbarRef.current.style.transform = `translate(${x.value}px, ${y.value}px)`; + if (refToolbar.current) { + refToolbar.current.style.transform = `translate(${x.value}px, ${y.value}px)`; } }, []); // Update toolbar position during drag useEffect(() => { const onMouseMove = (e: MouseEvent) => { - if (isDragging.value && toolbarRef.current) { + if (isDragging.value && refToolbar.current) { const newX = e.clientX - dragInitialXOffsetRef.current; const newY = e.clientY - dragInitialYOffsetRef.current; x.value = newX; y.value = newY; - toolbarRef.current.style.transform = `translate(${newX}px, ${newY}px)`; + refToolbar.current.style.transform = `translate(${newX}px, ${newY}px)`; persistPositionToLocalStorage(newX, newY); } }; @@ -499,14 +506,14 @@ export const Toolbar = ({ }, []); useSignalEffect(() => { - if (toolbarRef.current) { - toolbarRef.current.style.transform = `translate(${x.value}px, ${y.value}px)`; + if (refToolbar.current) { + refToolbar.current.style.transform = `translate(${x.value}px, ${y.value}px)`; } }); useEffect(() => { - if (toolbarRef.current) { - const rect = toolbarRef.current.getBoundingClientRect(); + if (refToolbar.current) { + const rect = refToolbar.current.getBoundingClientRect(); x.value = rect.left; y.value = rect.top; } @@ -519,262 +526,186 @@ export const Toolbar = ({ }); useEffect(() => { - if (!toolbarRef.current) return; + if (!refToolbar.current) return; const observer = new ResizeObserver(() => { ensureToolbarInBounds(); }); - observer.observe(toolbarRef.current); + observer.observe(refToolbar.current); return () => { observer.disconnect(); }; }, []); - useSignalEffect(() => { - if (Store.inspectState.value.kind === 'inspecting') { - // Clear previous props - if (propContainerRef.current) { - propContainerRef.current.innerHTML = ''; - } - } - }); - return (
-
onMouseDownToolbar(e as any)} + ref={refToolbarContent} + onMouseDown={onMouseDownToolbar} + className={cn( + 'flex flex-col', + 'w-fit', + 'bg-black/95', + 'border-1 border-white/10', + 'rounded-lg', + 'pointer-events-auto', + 'cursor-move', + 'text-white', + 'overflow-hidden', + 'transition-all duration-500 ease-[cubic-bezier(0,0.95,0.1,1)]', + 'box-shadow-[0_4px_12px_rgba(0,0,0,0.2)]', + )} > +
+
+ {/* Inject props content here if needed */} +
+ +
+
-
- {showNavButtons && ( - <> + { + focusActive && ( +
- - )} - - react-scan - -
+
+ ) + } + + react-scan +
-
- {/* Inject props content here if needed */} -
+
onMouseDownResize(e as any)} - style={{ - position: 'absolute', - left: 0, - top: 0, - bottom: 0, - width: '4px', - cursor: 'ew-resize', - display: focusActive ? 'block' : 'none', - }} + ref={refResizeHandle} + onMouseDown={onMouseDownResize} + className={cn( + 'absolute', + 'left-0', + 'top-0', + 'bottom-0', + 'w-1', + // 'cursor-ew-resize', + { + 'hidden': !focusActive, + } + )} />
); }; -export const createToolbar = () => { +export const createToolbar = (shadow: ShadowRoot) => { if (typeof window === 'undefined') { - return { - cleanup: () => { - /**/ - }, - }; + return; } - const existing = document.getElementById('react-scan-toolbar-root'); - if (existing) { - existing.remove(); - } - - const container = document.createElement('div'); - container.style.position = 'absolute'; - container.style.zIndex = '2147483647'; - container.id = 'react-scan-toolbar-root'; - document.documentElement.appendChild(container); - - const ToolbarWrapper = () => { - return ( - ( + <> + {/* { y={toolbarY} isDragging={isDragging} isResizing={isResizing} - /> - ); - }; - - render(, container); - - const cleanup = () => { - render(null, container); - container.remove(); - }; - - // eventually get rid of this shit - const TRANSITION_MS = '150ms'; - const styleElement = document.createElement('style'); - styleElement.textContent = ` - #react-scan-toolbar { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - z-index: 999999999; - } - - - .react-scan-inspector { - font-size: 13px; - width: 360px; - color: #fff; - width: 100%; - } - - .react-scan-header { - padding: 8px 12px; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - display: flex; - gap: 8px; - align-items: center; - justify-content: space-between; - background: #000; - } - - .react-scan-header-left { - display: flex; - gap: 8px; - align-items: center; - } - - .react-scan-header-right { - display: flex; - gap: 4px; - align-items: center; - } - - .react-scan-replay-button { - padding: 4px; - display: flex; - align-items: center; - justify-content: center; - background: rgba(255, 255, 255, 0.1); - border: none; - border-radius: 4px; - color: #fff; - cursor: pointer; - transition: all ${TRANSITION_MS} ease; - outline: none; - } - - .react-scan-replay-button:hover { - background: rgba(255, 255, 255, 0.15); - } - - .react-scan-component-name { - font-weight: 500; - color: #fff; - } - - .react-scan-metrics { - color: #888; - font-size: 12px; - } - - .react-scan-content { - padding: 12px; - background: #000; - } - - .react-scan-section { - color: #888; - margin-bottom: 16px; - font-size: 12px; - } - - .react-scan-section:last-child { - margin-bottom: 0; - } - - .react-scan-property { - margin-left: 14px; - margin-top: 8px; - position: relative; - } - - .react-scan-section > .react-scan-property:first-child { - margin-top: 4px; - } - - .react-scan-key { - color: #fff; - } - - .react-scan-warning { - padding-right: 4px; - } - - .react-scan-string { - color: #9ECBFF; - } - - .react-scan-number { - color: #79C7FF; - } - - .react-scan-boolean { - color: #56B6C2; - } - - .react-scan-input { - background: #000; - border: none; - color: #fff; - } - - .react-scan-object-key { - color: #fff; - } - - .react-scan-array { - color: #fff; - } - - .react-scan-expandable { - display: flex; - align-items: flex-start; - } - - .react-scan-arrow { - cursor: pointer; - content: '▶'; - display: inline-block; - font-size: 8px; - margin: 5px 4px 0 0; - transition: transform ${TRANSITION_MS} ease; - width: 8px; - flex-shrink: 0; - color: #888; - } - - .react-scan-expanded > .react-scan-arrow { - transform: rotate(90deg); - } - - .react-scan-property-content { - flex: 1; - min-width: 0; - } - - .react-scan-hidden { - display: none; - } - - .react-scan-array-container { - overflow-y: auto; - margin-left: 14px; - margin-top: 8px; - border-left: 1px solid rgba(255, 255, 255, 0.1); - padding-left: 8px; - } - - .react-scan-nested-object { - margin-left: 14px; - margin-top: 8px; - border-left: 1px solid rgba(255, 255, 255, 0.1); - padding-left: 8px; - } - - .react-scan-nested-object > .react-scan-property { - margin-top: 8px; - } - - .react-scan-nested-object > .react-scan-property:first-child { - margin-top: 0; - } - - .react-scan-preview-line { - position: relative; - padding: 3px 6px; - border-radius: 4px; - font-family: 'Menlo', 'Monaco', 'Courier New', monospace; - display: flex; - align-items: center; -} -.react-scan-flash-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(142, 97, 227, 1); - pointer-events: none; - opacity: 0; - z-index: 999999; - mix-blend-mode: multiply; - transition: opacity ${TRANSITION_MS} ease-in; - border-radius: 4px; -} - -.react-scan-flash-active { - opacity: 0.4; - transition: opacity 300ms ease-in-out; -} - - /* Hover states */ - #react-scan-toolbar button:hover { - background: rgba(255, 255, 255, 0.1); - } - - #react-scan-toolbar button:active { - background: rgba(255, 255, 255, 0.15); - } - - /* Focus states */ - #react-scan-toolbar button:focus-visible { - outline: 2px solid #0070F3; - outline-offset: -2px; - } - - /* Scrollbar styling */ - .react-scan-props::-webkit-scrollbar { - width: 6px; - height: 6px; - } - - .react-scan-props::-webkit-scrollbar-track { - background: transparent; - } - - .react-scan-props::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.2); - border-radius: 3px; - } - - .react-scan-props::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.3); - } - - - - #react-scan-toolbar::-webkit-scrollbar { - width: 4px; - height: 4px; - - } - - #react-scan-toolbar::-webkit-scrollbar-track { - background: rgba(255, 255, 255, 0.1); - border-radius: 4px; - } - - #react-scan-toolbar::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 4px; - } - - #react-scan-toolbar::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.4); - } - - /* For Firefox */ - #react-scan-toolbar * { - scrollbar-width: thin; - scrollbar-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.1); - } - - .nav-button { - opacity: var(--nav-opacity, 1); - } - `; - - document.head.appendChild(styleElement); + /> */} + + + ); - return { cleanup }; + render(, shadow); }; diff --git a/packages/scan/src/core/web/geiger.ts b/packages/scan/src/core/web/utils/geiger.ts similarity index 73% rename from packages/scan/src/core/web/geiger.ts rename to packages/scan/src/core/web/utils/geiger.ts index f65fa1c2..b658b214 100644 --- a/packages/scan/src/core/web/geiger.ts +++ b/packages/scan/src/core/web/utils/geiger.ts @@ -22,29 +22,46 @@ // Taken from: https://github.com/kristiandupont/react-geiger/blob/main/src/Geiger.tsx +// Simple throttle for high-frequency calls +let lastPlayTime = 0; +const MIN_INTERVAL = 32; // ~30fps throttle + +/** + * Plays a Geiger counter-like click sound + * Optimized for render tracking with minimal changes + */ export const playGeigerClickSound = ( audioContext: AudioContext, amplitude: number, ) => { + // Simple throttle to prevent audio overlap + const now = performance.now(); + if (now - lastPlayTime < MIN_INTERVAL) { + return; + } + lastPlayTime = now; + + // Cache currentTime for consistent timing + const currentTime = audioContext.currentTime; const volume = Math.max(0.5, amplitude); const duration = 0.001; const startFrequency = 440 + amplitude * 200; const oscillator = audioContext.createOscillator(); oscillator.type = 'sine'; - oscillator.frequency.setValueAtTime(startFrequency, audioContext.currentTime); + oscillator.frequency.setValueAtTime(startFrequency, currentTime); oscillator.frequency.exponentialRampToValueAtTime( 220, - audioContext.currentTime + duration, + currentTime + duration, ); const gainNode = audioContext.createGain(); - gainNode.gain.setValueAtTime(volume, audioContext.currentTime); + gainNode.gain.setValueAtTime(volume, currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, duration / 2); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.start(); - oscillator.stop(audioContext.currentTime + duration); + oscillator.stop(currentTime + duration); }; diff --git a/packages/scan/src/core/web/utils.ts b/packages/scan/src/core/web/utils/helpers.ts similarity index 60% rename from packages/scan/src/core/web/utils.ts rename to packages/scan/src/core/web/utils/helpers.ts index 20662285..a7b0efd7 100644 --- a/packages/scan/src/core/web/utils.ts +++ b/packages/scan/src/core/web/utils/helpers.ts @@ -1,5 +1,14 @@ +import { + type ClassValue, + clsx, +} from 'clsx'; +import { twMerge } from 'tailwind-merge'; import { type PendingOutline } from './outline'; +export const cn = (...inputs: Array): string => { + return twMerge(clsx(inputs)); +}; + export const onIdle = (callback: () => void) => { if ('scheduler' in globalThis) { return globalThis.scheduler.postTask(callback, { @@ -45,3 +54,31 @@ export const createElement = (htmlString: string): HTMLElement => { template.innerHTML = htmlString.trim(); return template.content.firstElementChild as HTMLElement; }; + + +export const tryOrElse = (cb: () => T, val: E) => { + try { + return cb(); + } catch (e) { + return val; + } +}; + +export const readLocalStorage = (storageKey: string): T | null => { + if (typeof window === 'undefined') return null; + try { + const stored = window.localStorage.getItem(storageKey); + return stored ? JSON.parse(stored) : null; + } catch { + return null; + } +}; + +export const saveLocalStorage = (storageKey: string, state: T): | void => { + if (typeof window === 'undefined') return; + try { + window.localStorage.setItem(storageKey, JSON.stringify(state)); + } catch { + // Silently fail + } +}; diff --git a/packages/scan/src/core/web/log.ts b/packages/scan/src/core/web/utils/log.ts similarity index 96% rename from packages/scan/src/core/web/log.ts rename to packages/scan/src/core/web/utils/log.ts index d31023e6..ebf3b5aa 100644 --- a/packages/scan/src/core/web/log.ts +++ b/packages/scan/src/core/web/utils/log.ts @@ -1,5 +1,5 @@ -import type { Render } from '../instrumentation'; -import { getLabelText } from '../utils'; +import type { Render } from '../../instrumentation'; +import { getLabelText } from '../../utils'; export const log = (renders: Array) => { const logMap = new Map< diff --git a/packages/scan/src/core/web/outline.ts b/packages/scan/src/core/web/utils/outline.ts similarity index 96% rename from packages/scan/src/core/web/outline.ts rename to packages/scan/src/core/web/utils/outline.ts index b653c745..47049766 100644 --- a/packages/scan/src/core/web/outline.ts +++ b/packages/scan/src/core/web/utils/outline.ts @@ -1,9 +1,9 @@ import { type Fiber } from 'react-reconciler'; import { getNearestHostFiber } from 'bippy'; -import type { Render } from '../instrumentation'; -import { ReactScanInternals } from '../index'; -import { getLabelText } from '../utils'; -import { isOutlineUnstable, throttle } from './utils'; +import type { Render } from '../../instrumentation'; +import { ReactScanInternals } from '../../index'; +import { getLabelText } from '../../utils'; +import { isOutlineUnstable, throttle } from './helpers'; export interface PendingOutline { rect: DOMRect; @@ -27,8 +27,6 @@ export interface OutlineLabel { color: { r: number; g: number; b: number }; } -export const MONO_FONT = - 'Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace'; const DEFAULT_THROTTLE_TIME = 32; // 2 frames const START_COLOR = { r: 115, g: 97, b: 230 }; @@ -327,7 +325,7 @@ export const fadeOutOutline = ( ctx.save(); if (text) { - ctx.font = `11px ${MONO_FONT}`; + ctx.font = `11px Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace`; const textMetrics = ctx.measureText(text); const textWidth = textMetrics.width; const textHeight = 11; diff --git a/packages/scan/src/monitoring/next.ts b/packages/scan/src/monitoring/next.ts index 0519ecba..e69de29b 100644 --- a/packages/scan/src/monitoring/next.ts +++ b/packages/scan/src/monitoring/next.ts @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/scan/src/react-component-name/__tests__/general-cases.test.ts b/packages/scan/src/react-component-name/__tests__/general-cases.test.ts index ecffb9e7..418a725d 100644 --- a/packages/scan/src/react-component-name/__tests__/general-cases.test.ts +++ b/packages/scan/src/react-component-name/__tests__/general-cases.test.ts @@ -30,7 +30,7 @@ describe('edge cases', () => { ))}
), [data]) - + return ( <> {isLoading ? : content} @@ -168,10 +168,10 @@ describe('edge cases', () => { } }; - const TernaryComponent = ({ condition, value }) => + const TernaryComponent = ({ condition, value }) => condition ? value - : value + : value ? {value} : null; @@ -290,7 +290,7 @@ describe('edge cases', () => { const [sortField, setSortField] = useState(null); const [sortDirection, setSortDirection] = useState('asc'); const [filters, setFilters] = useState({}); - + const sortedData = useMemo(() => { if (!sortField) return data; return [...data].sort((a, b) => { @@ -380,7 +380,7 @@ describe('edge cases', () => { const Field = React.forwardRef((props, ref) => { const [value, setValue] = useState(''); const internalRef = useRef(null); - + useImperativeHandle(ref, () => ({ focus: () => internalRef.current?.focus(), reset: () => setValue('') @@ -437,7 +437,7 @@ describe('edge cases', () => { ), (prevProps, nextProps) => prevProps.items === nextProps.items); - + // memo with type annotations const TypedButton = React.memo(props => (