├── .changeset
├── README.md
└── config.json
├── .github
├── CODE_OF_CONDUCT.md
├── assets
│ ├── airbnb-logo.png
│ ├── demo.gif
│ ├── faire-logo.svg
│ ├── github.mp4
│ ├── instagram.mp4
│ ├── logo.svg
│ ├── perplexity-logo.png
│ ├── shopify-logo.png
│ └── twitter.mp4
└── workflows
│ ├── build-extension.yml
│ └── pkg-pr-new.yaml
├── .gitignore
├── .npmrc
├── .vscode
└── settings.json
├── BROWSER_EXTENSION_GUIDE.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bin
├── generate-certs.sh
└── serve-scan.sh
├── biome.json
├── docs
└── installation
│ ├── astro.md
│ ├── cdn.md
│ ├── create-react-app.md
│ ├── next-js-app-router.md
│ ├── next-js-page-router.md
│ ├── parcel.md
│ ├── react-router.md
│ ├── remix.md
│ ├── rsbuild.md
│ ├── tanstack-start.md
│ └── vite.md
├── kitchen-sink
├── index.html
├── package.json
├── postcss.config.mjs
├── src
│ ├── examples
│ │ ├── sierpinski
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── todo-list
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ ├── index.css
│ ├── index.tsx
│ ├── main.css
│ └── main.tsx
├── tailwind.config.mjs
├── tsconfig.json
└── vite.config.ts
├── package.json
├── packages
├── extension
│ ├── .env.example
│ ├── .gitignore
│ ├── README.md
│ ├── build
│ │ ├── brave-extension-v1.0.9.zip
│ │ ├── chrome-extension-v1.0.9.zip
│ │ └── firefox-extension-v1.0.9.zip
│ ├── package.json
│ ├── public
│ │ └── icons
│ │ │ ├── disabled
│ │ │ ├── 128.png
│ │ │ ├── 16.png
│ │ │ ├── 32.png
│ │ │ └── 48.png
│ │ │ └── enabled
│ │ │ ├── 128.png
│ │ │ ├── 16.png
│ │ │ ├── 32.png
│ │ │ └── 48.png
│ ├── src
│ │ ├── assets
│ │ │ └── css
│ │ │ │ └── no-react.css
│ │ ├── background
│ │ │ ├── icon.ts
│ │ │ └── index.ts
│ │ ├── content
│ │ │ └── index.ts
│ │ ├── inject
│ │ │ ├── index.ts
│ │ │ ├── notification.ts
│ │ │ └── react-scan.ts
│ │ ├── manifest.chrome.json
│ │ ├── manifest.firefox.json
│ │ ├── types
│ │ │ ├── global.d.ts
│ │ │ └── messages.ts
│ │ ├── utils
│ │ │ ├── constants.ts
│ │ │ └── helpers.ts
│ │ └── vite-env.d.ts
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── scan
│ ├── .gitignore
│ ├── README.md
│ ├── auto.d.ts
│ ├── bin
│ │ └── cli.js
│ ├── global.d.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── postcss.rem2px.mjs
│ ├── scripts
│ │ └── bump-version.js
│ ├── src
│ │ ├── auto.ts
│ │ ├── cli.mts
│ │ ├── core
│ │ │ ├── fast-serialize.test.ts
│ │ │ ├── index.ts
│ │ │ ├── instrumentation.ts
│ │ │ ├── monitor
│ │ │ │ ├── constants.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── network.ts
│ │ │ │ ├── params
│ │ │ │ │ ├── astro
│ │ │ │ │ │ ├── Monitoring.astro
│ │ │ │ │ │ ├── component.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── next.ts
│ │ │ │ │ ├── react-router-v5.ts
│ │ │ │ │ ├── react-router-v6.ts
│ │ │ │ │ ├── remix.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── performance.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ │ ├── notifications
│ │ │ │ ├── event-tracking.ts
│ │ │ │ ├── interaction-store.ts
│ │ │ │ ├── outline-overlay.ts
│ │ │ │ ├── performance-store.ts
│ │ │ │ ├── performance-utils.ts
│ │ │ │ ├── performance.ts
│ │ │ │ └── types.ts
│ │ │ └── utils.ts
│ │ ├── index.ts
│ │ ├── install-hook.ts
│ │ ├── monitoring
│ │ │ └── next.ts
│ │ ├── new-outlines
│ │ │ ├── canvas.ts
│ │ │ ├── index.ts
│ │ │ ├── offscreen-canvas.worker.ts
│ │ │ └── types.ts
│ │ ├── polyfills.ts
│ │ ├── react-component-name
│ │ │ ├── __tests__
│ │ │ │ ├── arrow-function.test.ts
│ │ │ │ ├── complex-patterns.test.ts
│ │ │ │ ├── function-declarations.test.ts
│ │ │ │ ├── general-cases.test.ts
│ │ │ │ ├── react-patterns.test.ts
│ │ │ │ ├── ts-patterns.test.ts
│ │ │ │ └── utils.ts
│ │ │ ├── astro.ts
│ │ │ ├── babel
│ │ │ │ ├── get-descriptive-name.ts
│ │ │ │ ├── get-root-statement-path.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── is-componentish-name.ts
│ │ │ │ ├── is-nested-expression.ts
│ │ │ │ ├── is-path-valid.ts
│ │ │ │ ├── is-statement-top-level.ts
│ │ │ │ ├── path-references-import.ts
│ │ │ │ └── unwrap.ts
│ │ │ ├── core
│ │ │ │ └── options.ts
│ │ │ ├── esbuild.ts
│ │ │ ├── index.ts
│ │ │ ├── loader.ts
│ │ │ ├── rolldown.ts
│ │ │ ├── rollup.ts
│ │ │ ├── rspack.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── vite.ts
│ │ │ └── webpack.ts
│ │ ├── types.d.ts
│ │ ├── types.ts
│ │ ├── web
│ │ │ ├── assets
│ │ │ │ └── css
│ │ │ │ │ └── styles.tailwind.css
│ │ │ ├── components
│ │ │ │ ├── copy-to-clipboard
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── icon
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── slider
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── sticky-section
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── svg-sprite
│ │ │ │ │ └── index.tsx
│ │ │ │ └── toggle
│ │ │ │ │ └── index.tsx
│ │ │ ├── constants.ts
│ │ │ ├── hooks
│ │ │ │ ├── use-delayed-value.ts
│ │ │ │ ├── use-merged-refs.ts
│ │ │ │ └── use-virtual-list.ts
│ │ │ ├── state.ts
│ │ │ ├── toolbar.tsx
│ │ │ ├── utils
│ │ │ │ ├── constants.ts
│ │ │ │ ├── create-store.ts
│ │ │ │ ├── geiger.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── lerp.ts
│ │ │ │ ├── log.ts
│ │ │ │ ├── lru.ts
│ │ │ │ ├── outline.ts
│ │ │ │ ├── pin.ts
│ │ │ │ └── preact
│ │ │ │ │ ├── constant.ts
│ │ │ │ │ ├── use-constant.ts
│ │ │ │ │ └── use-lazy-ref.ts
│ │ │ ├── views
│ │ │ │ ├── index.tsx
│ │ │ │ ├── inspector
│ │ │ │ │ ├── components-tree
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── state.ts
│ │ │ │ │ ├── diff-value.tsx
│ │ │ │ │ ├── flash-overlay.ts
│ │ │ │ │ ├── header.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── logging.ts
│ │ │ │ │ ├── overlay
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── properties.tsx
│ │ │ │ │ ├── states.ts
│ │ │ │ │ ├── timeline
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── utils.ts
│ │ │ │ │ ├── utils.ts
│ │ │ │ │ ├── what-changed.tsx
│ │ │ │ │ └── whats-changed
│ │ │ │ │ │ └── use-change-store.ts
│ │ │ │ ├── notifications
│ │ │ │ │ ├── collapsed-event.tsx
│ │ │ │ │ ├── data.ts
│ │ │ │ │ ├── details-routes.tsx
│ │ │ │ │ ├── icons.tsx
│ │ │ │ │ ├── notification-header.tsx
│ │ │ │ │ ├── notification-tabs.tsx
│ │ │ │ │ ├── notifications.tsx
│ │ │ │ │ ├── optimize.tsx
│ │ │ │ │ ├── other-visualization.tsx
│ │ │ │ │ ├── popover.tsx
│ │ │ │ │ ├── render-bar-chart.tsx
│ │ │ │ │ ├── render-explanation.tsx
│ │ │ │ │ └── slowdown-history.tsx
│ │ │ │ ├── settings
│ │ │ │ │ └── header.tsx
│ │ │ │ └── toolbar
│ │ │ │ │ └── index.tsx
│ │ │ └── widget
│ │ │ │ ├── fps-meter.tsx
│ │ │ │ ├── header.tsx
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── resize-handle.tsx
│ │ │ │ └── types.ts
│ │ └── worker-shim.ts
│ ├── tailwind.config.mjs
│ ├── tsconfig.json
│ ├── tsup.config.ts
│ ├── vite.config.mts
│ └── worker-plugin.ts
├── vite-plugin-react-scan
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── global.d.ts
│ │ └── index.ts
│ └── tsconfig.json
└── website
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── app
│ ├── api
│ │ └── waitlist
│ │ │ └── route.ts
│ ├── favicon.ico
│ ├── fonts
│ │ ├── GeistMonoVF.woff
│ │ └── GeistVF.woff
│ ├── globals.css
│ ├── layout.tsx
│ ├── monitoring
│ │ ├── (components)
│ │ │ └── waitlist.tsx
│ │ └── page.tsx
│ ├── page.tsx
│ ├── react-scan.ts
│ └── replay
│ │ └── page.tsx
│ ├── components
│ ├── cli.tsx
│ ├── code.tsx
│ ├── companies.tsx
│ ├── counter.tsx
│ ├── footer.tsx
│ ├── header.tsx
│ ├── install-guide.tsx
│ ├── test-data-types.tsx
│ └── todo-demo.tsx
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public
│ ├── after.png
│ ├── airbnb-logo.png
│ ├── banner.png
│ ├── discord.svg
│ ├── faire-logo.svg
│ ├── logo.svg
│ ├── monitoring.png
│ ├── perplexity-logo.png
│ ├── player-video.mp4
│ ├── profiler.svg
│ ├── shopify-logo.png
│ └── thumbnail.png
│ ├── tailwind.config.ts
│ └── tsconfig.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── scripts
├── build-worker.ts
├── bump-version.js
├── version-warning.mjs
└── workspace.mjs
└── tsconfig.json
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "fixed": [["react-scan", "@react-scan/extension"]],
6 | "linked": [],
7 | "access": "public",
8 | "baseBranch": "main",
9 | "updateInternalDependencies": "patch",
10 | "ignore": []
11 | }
12 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at aiden.bai05@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | For answers to common questions about this code of conduct, see
74 | https://www.contributor-covenant.org/faq
--------------------------------------------------------------------------------
/.github/assets/airbnb-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/airbnb-logo.png
--------------------------------------------------------------------------------
/.github/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/demo.gif
--------------------------------------------------------------------------------
/.github/assets/github.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/github.mp4
--------------------------------------------------------------------------------
/.github/assets/instagram.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/instagram.mp4
--------------------------------------------------------------------------------
/.github/assets/perplexity-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/perplexity-logo.png
--------------------------------------------------------------------------------
/.github/assets/shopify-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/shopify-logo.png
--------------------------------------------------------------------------------
/.github/assets/twitter.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aidenybai/react-scan/6df072adeec70117b62bddf02981113596e0b99a/.github/assets/twitter.mp4
--------------------------------------------------------------------------------
/.github/workflows/build-extension.yml:
--------------------------------------------------------------------------------
1 | name: Build Extension
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths:
8 | - 'packages/extension/**'
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | permissions:
14 | contents: write
15 |
16 | steps:
17 | - uses: actions/checkout@v4
18 | with:
19 | fetch-depth: 0
20 | ref: main
21 |
22 | - name: Setup Node.js
23 | uses: actions/setup-node@v4
24 | with:
25 | node-version: '20'
26 |
27 | - name: Setup PNPM
28 | uses: pnpm/action-setup@v2
29 | with:
30 | version: 9.x
31 |
32 | - name: Install dependencies
33 | run: pnpm install
34 |
35 | - name: Get package info
36 | id: package
37 | run: |
38 | echo "name=$(node -p "require('./packages/extension/package.json').name")" >> $GITHUB_OUTPUT
39 | echo "version=$(node -p "require('./packages/extension/package.json').version")" >> $GITHUB_OUTPUT
40 |
41 | - name: Build extensions
42 | run: |
43 | pnpm build
44 | cd packages/extension
45 | rm -rf build
46 | pnpm pack:all
47 |
48 | - name: Commit changes
49 | if: github.ref == 'refs/heads/main'
50 | run: |
51 | git checkout main
52 | git config --local user.email "github-actions[bot]@users.noreply.github.com"
53 | git config --local user.name "github-actions[bot]"
54 | git add -f packages/extension/build/*.zip
55 | git diff --staged --quiet || (git commit -m "chore: update extension builds [skip ci]" && git push)
56 |
--------------------------------------------------------------------------------
/.github/workflows/pkg-pr-new.yaml:
--------------------------------------------------------------------------------
1 | name: Publish Any Commit
2 | on:
3 | push:
4 | branches:
5 | - "**"
6 | pull_request:
7 | branches:
8 | - "**"
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | node-version: [18]
16 |
17 | steps:
18 | - uses: actions/checkout@v4
19 |
20 | - name: Install pnpm
21 | uses: pnpm/action-setup@v4
22 | with:
23 | version: 9.1.0
24 |
25 | - name: Use Node.js ${{ matrix.node-version }}
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version: ${{ matrix.node-version }}
29 | cache: "pnpm"
30 |
31 | - name: Install dependencies
32 | run: pnpm install --frozen-lockfile --strict-peer-dependencies=false
33 |
34 | - name: Build
35 | run: |
36 | cd packages/scan
37 | NODE_ENV=production pnpm build
38 | env:
39 | NODE_ENV: production
40 |
41 | - name: Publish NPM Package to pkg-pr-new
42 | run: pnpx pkg-pr-new publish ./packages/scan
43 | env:
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | .env
4 | dist
5 | **/*.tgz
6 | *.log
7 | build
8 | !packages/extension/build/
9 | playgrounds
10 | # SSL Certificates
11 | bin/certs/*.pem
12 | bin/certs/*.key
13 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | prefer-workspace-packages=true
2 | link-workspace-packages=true
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "biomejs.biome",
3 | "editor.formatOnSave": true,
4 | "editor.codeActionsOnSave": {
5 | "source.organizeImports.biome": "always",
6 | "quickfix.biome": "always"
7 | },
8 | "css.lint.unknownAtRules": "ignore",
9 | "[typescript]": {
10 | "editor.defaultFormatter": "biomejs.biome"
11 | },
12 | "[javascript]": {
13 | "editor.defaultFormatter": "biomejs.biome"
14 | },
15 | "[json]": {
16 | "editor.defaultFormatter": "biomejs.biome"
17 | },
18 | "[markdown]": {
19 | "editor.defaultFormatter": "esbenp.prettier-vscode"
20 | },
21 | "[html]": {
22 | "editor.defaultFormatter": "esbenp.prettier-vscode"
23 | },
24 | "typescript.tsdk": "node_modules/typescript/lib",
25 | "[css]": {
26 | "editor.defaultFormatter": "biomejs.biome"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/BROWSER_EXTENSION_GUIDE.md:
--------------------------------------------------------------------------------
1 | # Browser Extension Installation Guide
2 |
3 | > [!NOTE]
4 | > The React Scan browser extension currently uses `react-scan@0.2.9`
5 |
6 |
7 | ## Chrome
8 | > You can download the Chrome browser extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/react-scan/anmmhkomejbdklkhoiloeaehppaffmdf). Below is a guide to installing the extension manually.
9 |
10 | 1. Download the [`chrome-extension-v1.0.8.zip`](https://github.com/aidenybai/react-scan/tree/main/packages/extension/build) file.
11 | 2. Unzip the file.
12 | 3. Open Chrome and navigate to `chrome://extensions/`.
13 | 4. Enable "Developer mode" if it is not already enabled.
14 | 5. Click "Load unpacked" and select the unzipped folder (or drag the folder into the page).
15 |
16 | ## Firefox
17 | > React Scan's Browser extension is still pending approvals from Firefox Add-ons. Below is a guide to installing the extension manually.
18 | 1. Download the [`firefox-extension-v1.0.8.zip`](https://github.com/aidenybai/react-scan/tree/main/packages/extension/build) file.
19 | 2. Unzip the file.
20 | 3. Open Firefox and navigate to `about:debugging#/runtime/this-firefox`.
21 | 4. Click "Load Temporary Add-on..."
22 | 5. Select `manifest.json` from the unzipped folder
23 |
24 | ## Brave
25 | > React Scan's Browser extension is still pending approvals from Brave Browser. Below is a guide to installing the extension manually.
26 |
27 | 1. Download the [`brave-extension-v1.0.8.zip`](https://github.com/aidenybai/react-scan/tree/main/packages/extension/build) file.
28 | 2. Unzip the file.
29 | 3. Open Brave and navigate to `brave://extensions`.
30 | 4. Click "Load unpacked" and select the unzipped folder (or drag the folder into the page).
31 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to React Scan
2 |
3 | First off, thanks for taking the time to contribute! ❤️
4 |
5 | ## Table of Contents
6 |
7 | - [Contributing to React Scan](#contributing-to-react-scan)
8 | - [Table of Contents](#table-of-contents)
9 | - [Project Structure](#project-structure)
10 | - [Development Setup](#development-setup)
11 | - [Contributing Guidelines](#contributing-guidelines)
12 | - [Commits](#commits)
13 | - [Pull Request Process](#pull-request-process)
14 | - [Development Workflow](#development-workflow)
15 | - [Getting Help](#getting-help)
16 |
17 | ## Project Structure
18 |
19 | This is a monorepo containing several packages:
20 |
21 | - `packages/scan` - Core React Scan package
22 | - `packages/vite-plugin-react-scan` - Vite plugin for React Scan
23 | - `packages/extension` - VS Code extension
24 |
25 | ## Development Setup
26 |
27 | 1. **Clone and Install**
28 | ```bash
29 | git clone https://github.com/aidenybai/react-scan.git
30 | cd react-scan
31 | pnpm install
32 | ```
33 |
34 | 2. **Build all packages**
35 | ```bash
36 | pnpm build
37 | ```
38 |
39 | 3. **Testing React Scan**
40 | ```bash
41 | cd packages/scan
42 | pnpm build:copy
43 | ```
44 | - This will build the package and then copy it to your clipboard as an IIFE (immedietely invoked function expression). This will allow you to paste it into the browser console to test it on any website
45 |
46 | https://github.com/user-attachments/assets/f279e664-479f-4e39-bff4-1bbfee30af22
47 |
48 | ## Contributing Guidelines
49 |
50 | ### Commits
51 |
52 | We use conventional commits to ensure consistent commit messages:
53 |
54 | - `feat:` New features
55 | - `fix:` Bug fixes
56 | - `docs:` Documentation changes
57 | - `chore:` Maintenance tasks
58 | - `test:` Adding or updating tests
59 | - `refactor:` Code changes that neither fix bugs nor add features
60 |
61 | Example: `fix(scan): fix a typo`
62 |
63 | ### Pull Request Process
64 |
65 | 1. Fork the repository
66 | 2. Create your feature branch (`git checkout -b feat/amazing-feature`)
67 | 3. Commit your changes using conventional commits
68 | 4. Push to your branch
69 | 5. Open a Pull Request
70 | 6. Ask for reviews (@pivanov, @RobPruzan are your friends in this journey)
71 |
72 | ### Development Workflow
73 |
74 | 1. **TypeScript**
75 | - All code must be written in TypeScript
76 | - Ensure strict type checking passes
77 | - No `any` types unless absolutely necessary
78 |
79 | 2. **Code Style**
80 | - We use Biome for formatting and linting
81 | - Run `pnpm format` to format code
82 | - Run `pnpm lint` to check for issues
83 |
84 | 3. **Documentation**
85 | - Update relevant documentation
86 | - Add JSDoc comments for public APIs
87 | - Update README if needed
88 |
89 | ## Getting Help
90 | - Check existing issues
91 | - Create a new issue
92 |
93 |
94 |
95 | ⚛️ Happy coding! 🚀
96 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2025 Aiden Bai, Million Software, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/bin/generate-certs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir -p bin/certs
4 | openssl req -x509 -newkey rsa:2048 -keyout bin/certs/key.pem -out bin/certs/cert.pem -days 365 -nodes -subj "/CN=127.0.0.1"
5 |
--------------------------------------------------------------------------------
/bin/serve-scan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Determine the directory of the script
4 | SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5 |
6 | # Default values
7 | DEFAULT_PATH="./packages/scan/dist"
8 | DEFAULT_PORT="4000"
9 | DEFAULT_CERT="$SCRIPT_DIR/certs/cert.pem"
10 | DEFAULT_KEY="$SCRIPT_DIR/certs/key.pem"
11 |
12 | # Positional arguments
13 | SERVE_PATH="$1" # First argument is the path
14 |
15 | # Get optional flags
16 | shift # Remove the first argument from the list
17 | while [[ "$#" -gt 0 ]]; do
18 | case $1 in
19 | --port) PORT_ARG="$2"; shift ;;
20 | --cert) CERT_ARG="$2"; shift ;;
21 | --key) KEY_ARG="$2"; shift ;;
22 | *) echo "Unknown parameter: $1" >&2; exit 1 ;;
23 | esac
24 | shift
25 | done
26 |
27 | # Use provided arguments or defaults
28 | SERVE_PATH="${SERVE_PATH:-$DEFAULT_PATH}"
29 | SERVE_PORT="${PORT_ARG:-$DEFAULT_PORT}"
30 | SERVE_CERT="${CERT_ARG:-$DEFAULT_CERT}"
31 | SERVE_KEY="${KEY_ARG:-$DEFAULT_KEY}"
32 |
33 | # Run the server with CORS enabled
34 | http-server "$SERVE_PATH" -p "$SERVE_PORT" --ssl --cert "$SERVE_CERT" --key "$SERVE_KEY" --cors
35 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3 | "vcs": {
4 | "enabled": false,
5 | "clientKind": "git",
6 | "useIgnoreFile": false
7 | },
8 | "files": {
9 | "ignoreUnknown": false,
10 | "ignore": [
11 | "**/dist/**",
12 | "**/build/**",
13 | "node_modules",
14 | "**/node_modules/**",
15 | "**/*.css",
16 | "**/*.astro",
17 | "packages/website"
18 | ]
19 | },
20 | "organizeImports": {
21 | "enabled": false
22 | },
23 | "linter": {
24 | "enabled": true,
25 | "rules": {
26 | "recommended": false,
27 | "correctness": {
28 | "noUnusedFunctionParameters": {
29 | "level": "warn",
30 | "fix": "unsafe"
31 | },
32 | "noUnusedImports": {
33 | "level": "warn",
34 | "fix": "unsafe"
35 | },
36 | "noUnusedLabels": {
37 | "level": "warn",
38 | "fix": "unsafe"
39 | },
40 | "noUnusedPrivateClassMembers": {
41 | "level": "warn",
42 | "fix": "unsafe"
43 | },
44 | "noUnusedVariables": {
45 | "level": "warn",
46 | "fix": "unsafe"
47 | },
48 | "useExhaustiveDependencies": "warn"
49 | },
50 | "suspicious": {
51 | "noExplicitAny": "warn",
52 | "noConsole": "warn"
53 | },
54 | "security": {
55 | "noDangerouslySetInnerHtml": "error"
56 | },
57 | "style": {
58 | "noNonNullAssertion": "warn"
59 | }
60 | }
61 | },
62 | "formatter": {
63 | "enabled": true,
64 | "indentStyle": "space",
65 | "indentWidth": 2,
66 | "lineWidth": 80,
67 | "lineEnding": "lf"
68 | },
69 | "javascript": {
70 | "formatter": {
71 | "quoteStyle": "single",
72 | "trailingCommas": "all"
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/docs/installation/astro.md:
--------------------------------------------------------------------------------
1 | # Astro Guide
2 |
3 | ## As a script tag
4 |
5 | Add the script tag to your root layout.
6 |
7 | Refer to the [CDN Guide](https://github.com/aidenybai/react-scan/blob/main/docs/installation/cdn.md) for the available URLs.
8 |
9 | ```astro
10 |
11 |
12 |
{user.email}
14 |( 13 | Component: FunctionComponent
, 14 | ) { 15 | function Memoed(this: Component
, props: P) { 16 | this.shouldComponentUpdate = CONSTANT_UPDATE; 17 | return createElement
(Component, props);
18 | }
19 | Memoed.displayName = `Memo(${Component.displayName || Component.name})`;
20 | Memoed.prototype.isReactComponent = true;
21 | Memoed._forwarded = true;
22 | return Memoed;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/scan/src/web/utils/preact/use-constant.ts:
--------------------------------------------------------------------------------
1 | import { useDebugValue } from 'preact/hooks';
2 | import { useLazyRef } from './use-lazy-ref';
3 |
4 | export function useConstant {errorMessage} Successfully joined waitlist!
60 | $ {command}
61 |
73 |
74 |