├── .editorconfig ├── .github ├── FUNDING.yml ├── renovate.json └── workflows │ ├── autofix.yml │ ├── ci.yml │ ├── pkg.pr.new.yml │ └── release.yml ├── .gitignore ├── .node-version ├── .npmrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── bump.config.ts ├── docs ├── .vitepress │ ├── components │ │ ├── Home.vue │ │ ├── HomeContributors.vue │ │ ├── HomeSponsors.vue │ │ └── UseModeList.vue │ ├── config.ts │ ├── theme │ │ ├── index.ts │ │ └── style.css │ ├── uno.config.ts │ └── vite.config.ts ├── getting-started │ ├── features.md │ ├── installation.md │ ├── introduction.md │ └── open-in-editor.md ├── guide │ ├── browser-extension.md │ ├── migration.md │ ├── standalone.md │ └── vite-plugin.md ├── help │ ├── contributing.md │ ├── faq.md │ └── troubleshooting.md ├── index.md ├── netlify.toml ├── package.json ├── plugins │ └── api.md └── public │ ├── features │ ├── assets.png │ ├── chrome-logo.svg │ ├── chromium-logo.svg │ ├── command-palette.png │ ├── components.png │ ├── electron-connection.png │ ├── electron-logo.svg │ ├── electron.png │ ├── graph.png │ ├── inspect.png │ ├── inspector.png │ ├── multi-app.png │ ├── overview.png │ ├── pages.png │ ├── pinia-timeline.png │ ├── pinia.png │ ├── router.png │ ├── separate-window.png │ ├── settings.png │ ├── split-screen.png │ ├── timeline.png │ ├── timeline.svg │ └── vite-logo.svg │ ├── logo-1.svg │ ├── logo-mini.svg │ ├── logo.svg │ └── screenshots │ └── nested-issue.png ├── eslint-plugins ├── index.ts ├── rules │ └── no-vue-runtime-import │ │ ├── index.ts │ │ └── no-vue-runtime-import.test.ts ├── test-utils.ts └── utils.ts ├── eslint.config.ts ├── package.json ├── packages ├── applet │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── basic │ │ │ │ ├── AppConnecting.vue │ │ │ │ ├── DevToolsHeader.vue │ │ │ │ ├── Empty.vue │ │ │ │ ├── Navbar.vue │ │ │ │ ├── NodeTag.vue │ │ │ │ ├── SelectiveList.vue │ │ │ │ └── ToggleExpanded.vue │ │ │ ├── settings │ │ │ │ └── Settings.vue │ │ │ ├── state │ │ │ │ ├── ChildStateViewer.vue │ │ │ │ ├── RootStateViewer.vue │ │ │ │ ├── StateFieldEditor.vue │ │ │ │ ├── StateFieldInputEditor.vue │ │ │ │ └── StateFieldViewer.vue │ │ │ ├── timeline │ │ │ │ ├── EventList.vue │ │ │ │ └── index.vue │ │ │ └── tree │ │ │ │ └── TreeViewer.vue │ │ ├── composables │ │ │ ├── component-highlight.ts │ │ │ ├── custom-inspector-state.ts │ │ │ ├── custom-inspector.ts │ │ │ ├── hover.ts │ │ │ ├── select.ts │ │ │ ├── state-editor.ts │ │ │ ├── toggle-expanded.ts │ │ │ └── virtual-router.ts │ │ ├── index.ts │ │ ├── modules │ │ │ ├── components │ │ │ │ ├── components │ │ │ │ │ └── RenderCode.vue │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── custom-inspector │ │ │ │ ├── components │ │ │ │ │ ├── About.vue │ │ │ │ │ ├── DevToolsLogo.vue │ │ │ │ │ ├── Settings.vue │ │ │ │ │ ├── state │ │ │ │ │ │ └── Index.vue │ │ │ │ │ └── timeline │ │ │ │ │ │ └── Index.vue │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── pinia │ │ │ │ ├── components │ │ │ │ │ ├── About.vue │ │ │ │ │ ├── DevToolsLogo.vue │ │ │ │ │ ├── Settings.vue │ │ │ │ │ ├── store │ │ │ │ │ │ └── Index.vue │ │ │ │ │ └── timeline │ │ │ │ │ │ └── Index.vue │ │ │ │ ├── constants.ts │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ └── router │ │ │ │ ├── components │ │ │ │ ├── About.vue │ │ │ │ ├── DevToolsLogo.vue │ │ │ │ ├── routes │ │ │ │ │ └── Index.vue │ │ │ │ └── timeline │ │ │ │ │ └── Index.vue │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ ├── styles │ │ │ └── base.css │ │ └── utils │ │ │ ├── color.ts │ │ │ ├── date.ts │ │ │ ├── index.ts │ │ │ └── search.ts │ ├── tsconfig.json │ ├── uno.config.ts │ └── vite.config.ts ├── chrome-extension │ ├── README.md │ ├── icons │ │ ├── 128-beta.png │ │ ├── 128-gray.png │ │ ├── 128.nuxt.png │ │ ├── 128.png │ │ ├── 128.vitepress.png │ │ ├── 16-beta.png │ │ ├── 16-gray.png │ │ ├── 16.nuxt.png │ │ ├── 16.png │ │ ├── 16.vitepress.png │ │ ├── 48-beta.png │ │ ├── 48-gray.png │ │ ├── 48.nuxt.png │ │ ├── 48.png │ │ └── 48.vitepress.png │ ├── manifest.json │ ├── package.json │ ├── pages │ │ ├── devtools-background.html │ │ └── devtools-panel.html │ ├── popups │ │ ├── devtools-screenshot.png │ │ ├── disabled.html │ │ ├── disabled.nuxt.html │ │ ├── disabled.vitepress.html │ │ ├── enabled.html │ │ ├── enabled.nuxt.html │ │ ├── enabled.vitepress.html │ │ ├── not-found.html │ │ ├── popup.css │ │ └── vue2-migration-guide.html │ ├── src │ │ ├── background.ts │ │ ├── detector.ts │ │ ├── devtools-background.ts │ │ ├── devtools-overlay.ts │ │ ├── devtools-panel.ts │ │ ├── prepare.ts │ │ ├── proxy.ts │ │ └── user-app.ts │ └── tsup.config.ts ├── client │ ├── README.md │ ├── data │ │ └── vue-apis.json │ ├── index.html │ ├── package.json │ ├── public │ │ ├── color-scheme.js │ │ └── logo.svg │ ├── scripts │ │ └── pre-build.ts │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── images │ │ │ │ └── vue-logo.svg │ │ │ └── styles │ │ │ │ └── main.css │ │ ├── components │ │ │ ├── AppConnecting.vue │ │ │ ├── CommandPalette.vue │ │ │ ├── CustomTabComponent.vue │ │ │ ├── WaitForConnection.vue │ │ │ ├── assets │ │ │ │ ├── AssetDetails.vue │ │ │ │ ├── AssetDropZone.vue │ │ │ │ ├── AssetFontPreview.vue │ │ │ │ ├── AssetGridItem.vue │ │ │ │ ├── AssetListItem.vue │ │ │ │ ├── AssetPreview.vue │ │ │ │ └── FilepathItem.vue │ │ │ ├── chrome │ │ │ │ └── ViewModeSwitch.vue │ │ │ ├── code │ │ │ │ └── CodeSnippets.vue │ │ │ ├── common │ │ │ │ ├── DevToolsLogo.vue │ │ │ │ ├── DockingPanel.vue │ │ │ │ ├── EmptyPane.vue │ │ │ │ ├── ExpandIcon.vue │ │ │ │ ├── IconTitle.vue │ │ │ │ ├── IframeView.vue │ │ │ │ ├── Navbar.vue │ │ │ │ ├── PanelGrids.vue │ │ │ │ ├── SFCView.vue │ │ │ │ ├── SectionBlock.vue │ │ │ │ ├── SideNav.vue │ │ │ │ ├── SideNavItem.vue │ │ │ │ ├── SplitScreen.vue │ │ │ │ ├── TabIcon.vue │ │ │ │ └── TabsGrid.vue │ │ │ ├── graph │ │ │ │ ├── GraphDrawer.vue │ │ │ │ ├── GraphFileType.vue │ │ │ │ └── GraphNavbar.vue │ │ │ ├── pages │ │ │ │ ├── RouteMetaDetail.vue │ │ │ │ ├── RoutePathItem.vue │ │ │ │ ├── RoutesTable.vue │ │ │ │ └── __test__ │ │ │ │ │ └── routePathItem.test.ts │ │ │ └── timeline │ │ │ │ └── TimelineLayers.vue │ │ ├── composables │ │ │ ├── app.ts │ │ │ ├── collapse.ts │ │ │ ├── custom-inspector-tabs.ts │ │ │ ├── editor.ts │ │ │ ├── graph.ts │ │ │ ├── host.ts │ │ │ ├── hover.ts │ │ │ ├── inspector.ts │ │ │ ├── open-in-editor.ts │ │ │ ├── select.ts │ │ │ ├── state-commands.ts │ │ │ ├── state-tab.ts │ │ │ ├── state.ts │ │ │ └── view-mode.ts │ │ ├── constants │ │ │ └── tab.ts │ │ ├── index.ts │ │ ├── main.ts │ │ ├── pages │ │ │ ├── assets.vue │ │ │ ├── components.vue │ │ │ ├── custom-inspector-tab-view.vue │ │ │ ├── custom-tab-view.vue │ │ │ ├── graph.vue │ │ │ ├── overview.vue │ │ │ ├── pages.vue │ │ │ ├── pinia.vue │ │ │ ├── router.vue │ │ │ ├── settings.vue │ │ │ └── timeline.vue │ │ ├── setup │ │ │ └── unocss-runtime.ts │ │ ├── types │ │ │ ├── index.ts │ │ │ └── tab.ts │ │ └── utils │ │ │ ├── color.ts │ │ │ ├── index.ts │ │ │ └── time.ts │ ├── tsconfig.json │ ├── uno.config.ts │ ├── vite.base.config.ts │ ├── vite.config.ts │ └── vite.lib.config.ts ├── core │ ├── README.md │ ├── package.json │ ├── src │ │ ├── client.ts │ │ ├── index.ts │ │ ├── rpc │ │ │ ├── global.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── vite.ts │ │ └── vue-plugin │ │ │ └── devtools-state.ts │ └── tsup.config.ts ├── devtools-api │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsup.config.ts ├── devtools-kit │ ├── README.md │ ├── __tests__ │ │ ├── component │ │ │ ├── decode-state.test.ts │ │ │ ├── editor.test.ts │ │ │ └── format.test.ts │ │ └── fixtures │ │ │ ├── App.vue │ │ │ └── components │ │ │ └── Name.vue │ ├── global.d.ts │ ├── package.json │ ├── src │ │ ├── api │ │ │ ├── index.ts │ │ │ ├── v6 │ │ │ │ └── index.ts │ │ │ └── v7 │ │ │ │ └── index.ts │ │ ├── compat │ │ │ └── index.ts │ │ ├── core │ │ │ ├── app │ │ │ │ └── index.ts │ │ │ ├── component-highlighter │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── component-inspector │ │ │ │ └── index.ts │ │ │ ├── component │ │ │ │ ├── state │ │ │ │ │ ├── bounding-rect.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── custom.ts │ │ │ │ │ ├── editor.ts │ │ │ │ │ ├── format.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── is.ts │ │ │ │ │ ├── process.ts │ │ │ │ │ ├── replacer.ts │ │ │ │ │ ├── reviver.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── tree │ │ │ │ │ ├── el.ts │ │ │ │ │ ├── filter.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── walker.ts │ │ │ │ ├── types │ │ │ │ │ ├── bounding-rect.ts │ │ │ │ │ ├── custom.ts │ │ │ │ │ ├── editor.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── state.ts │ │ │ │ │ └── tree.ts │ │ │ │ └── utils │ │ │ │ │ └── index.ts │ │ │ ├── devtools-client │ │ │ │ └── detected.ts │ │ │ ├── high-perf-mode │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── open-in-editor │ │ │ │ └── index.ts │ │ │ ├── plugin │ │ │ │ ├── components.ts │ │ │ │ ├── index.ts │ │ │ │ └── plugin-settings.ts │ │ │ ├── router │ │ │ │ └── index.ts │ │ │ ├── timeline │ │ │ │ ├── index.ts │ │ │ │ ├── perf.ts │ │ │ │ └── storage.ts │ │ │ └── vm │ │ │ │ └── index.ts │ │ ├── ctx │ │ │ ├── api.ts │ │ │ ├── env.ts │ │ │ ├── hook.ts │ │ │ ├── index.ts │ │ │ ├── inspector.ts │ │ │ ├── plugin.ts │ │ │ ├── router.ts │ │ │ ├── state.ts │ │ │ └── timeline.ts │ │ ├── hook │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── messaging │ │ │ ├── index.ts │ │ │ ├── presets │ │ │ │ ├── broadcast-channel │ │ │ │ │ ├── context.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── electron │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── proxy.ts │ │ │ │ │ └── server.ts │ │ │ │ ├── extension │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── proxy.ts │ │ │ │ │ └── server.ts │ │ │ │ ├── iframe │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── server.ts │ │ │ │ ├── index.ts │ │ │ │ ├── vite │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── server.ts │ │ │ │ └── ws │ │ │ │ │ ├── client.ts │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── server.ts │ │ │ └── types │ │ │ │ ├── channel.ts │ │ │ │ └── index.ts │ │ ├── shared │ │ │ ├── __test__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── transfer.test.ts.snap │ │ │ │ └── transfer.test.ts │ │ │ ├── env.ts │ │ │ ├── index.ts │ │ │ ├── stub-vue.ts │ │ │ ├── time.ts │ │ │ ├── transfer.ts │ │ │ └── util.ts │ │ └── types │ │ │ ├── app.ts │ │ │ ├── command.ts │ │ │ ├── component.ts │ │ │ ├── hook.ts │ │ │ ├── index.ts │ │ │ ├── inspector.ts │ │ │ ├── plugin.ts │ │ │ ├── router.ts │ │ │ ├── tab.ts │ │ │ └── timeline.ts │ ├── tsup.config.ts │ └── types.d.ts ├── devtools │ ├── README.md │ ├── cli.mjs │ ├── hook.d.ts │ ├── package.json │ ├── src │ │ ├── hook.ts │ │ └── index.ts │ └── tsup.config.ts ├── electron │ ├── README.md │ ├── app.html │ ├── cli.d.ts │ ├── icons │ │ ├── 128-gray.png │ │ ├── 128.png │ │ ├── 16-gray.png │ │ ├── 16.png │ │ ├── 48-gray.png │ │ └── 48.png │ ├── package.json │ ├── scripts │ │ └── build.ts │ └── src │ │ ├── app.ts │ │ ├── cli.ts │ │ ├── devtools.ts │ │ ├── index.ts │ │ ├── server.ts │ │ ├── user-app.core.ts │ │ ├── user-app.iife.ts │ │ └── user-app.ts ├── firefox-extension │ ├── README.md │ ├── devtools-background.html │ ├── devtools-panel.html │ ├── icons │ │ ├── 128-beta.png │ │ ├── 128-gray.png │ │ ├── 128.nuxt.png │ │ ├── 128.png │ │ ├── 16-beta.png │ │ ├── 16-gray.png │ │ ├── 16.nuxt.png │ │ ├── 16.png │ │ ├── 48-beta.png │ │ ├── 48-gray.png │ │ ├── 48.nuxt.png │ │ └── 48.png │ ├── manifest.json │ ├── package.json │ ├── popups │ │ ├── devtools-screenshot.png │ │ ├── disabled.html │ │ ├── disabled.nuxt.html │ │ ├── disabled.vitepress.html │ │ ├── enabled.html │ │ ├── enabled.nuxt.html │ │ ├── enabled.vitepress.html │ │ ├── not-found.html │ │ ├── popup.css │ │ └── vue2-migration-guide.html │ ├── src │ │ ├── background.ts │ │ ├── detector.ts │ │ ├── devtools-background.ts │ │ ├── devtools-overlay.ts │ │ ├── devtools-panel.ts │ │ ├── injection.ts │ │ ├── prepare.ts │ │ ├── proxy.ts │ │ └── user-app.ts │ └── tsup.config.ts ├── overlay │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.vue │ │ ├── components │ │ │ └── FrameBox.vue │ │ ├── composables │ │ │ ├── iframe.ts │ │ │ ├── index.ts │ │ │ ├── panel.ts │ │ │ ├── position.ts │ │ │ └── state.ts │ │ ├── constants │ │ │ └── index.ts │ │ ├── main.ts │ │ └── utils │ │ │ └── index.ts │ ├── tsconfig.json │ └── vite.config.ts ├── playground │ ├── applet │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ └── color-scheme.js │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── components │ │ │ │ ├── Foo.vue │ │ │ │ ├── Hello.vue │ │ │ │ └── Tres.vue │ │ │ ├── main.ts │ │ │ ├── stores │ │ │ │ └── index.ts │ │ │ └── style.css │ │ ├── uno.config.ts │ │ └── vite.config.ts │ ├── basic │ │ ├── assets │ │ │ └── asset-in-root-assets.md │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ ├── assets │ │ │ │ └── asset-in-public-assets.md │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── components │ │ │ │ ├── DynamicApp.vue │ │ │ │ ├── Foo.vue │ │ │ │ ├── IndexComponent │ │ │ │ │ └── index.vue │ │ │ │ ├── Post.vue │ │ │ │ ├── Posts.vue │ │ │ │ └── PropChild.vue │ │ │ ├── main.ts │ │ │ ├── pages │ │ │ │ ├── CircularState.vue │ │ │ │ ├── Hello.vue │ │ │ │ ├── Hey.vue │ │ │ │ ├── Home.vue │ │ │ │ ├── IntervalUpdate.vue │ │ │ │ ├── PropMutation.vue │ │ │ │ ├── VeeValidate.vue │ │ │ │ └── VueQuery.vue │ │ │ ├── stores │ │ │ │ ├── index.ts │ │ │ │ └── vuexStore.ts │ │ │ └── style.css │ │ ├── uno.config.ts │ │ └── vite.config.ts │ ├── multi-app │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── App2.vue │ │ │ ├── components │ │ │ │ └── Number.vue │ │ │ ├── main.ts │ │ │ └── style.css │ │ ├── uno.config.ts │ │ └── vite.config.ts │ ├── options-api │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── Options.vue │ │ │ ├── Setup.vue │ │ │ ├── main.ts │ │ │ └── style.css │ │ ├── uno.config.ts │ │ └── vite.config.ts │ ├── plugin-sfc │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── count.vue │ │ │ └── main.ts │ │ └── vite.config.ts │ ├── ui │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── main.ts │ │ │ ├── style.css │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── uno.config.ts │ │ └── vite.config.ts │ └── webpack │ │ ├── babel.config.js │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ └── HelloWorld.vue │ │ └── main.js │ │ └── vue.config.js ├── shared │ ├── README.md │ ├── package.json │ ├── src │ │ ├── constants.ts │ │ ├── env.ts │ │ ├── general.ts │ │ └── index.ts │ └── tsup.config.ts ├── ui │ ├── README.md │ ├── env.d.ts │ ├── package.json │ ├── scripts │ │ └── update-icons.ts │ ├── src │ │ ├── components │ │ │ ├── Badge.vue │ │ │ ├── Button.vue │ │ │ ├── Card.vue │ │ │ ├── Checkbox.vue │ │ │ ├── CodeBlock.vue │ │ │ ├── Confirm.vue │ │ │ ├── DarkToggle.vue │ │ │ ├── Dialog.vue │ │ │ ├── Drawer.vue │ │ │ ├── Dropdown.vue │ │ │ ├── DropdownButton.vue │ │ │ ├── FormField.vue │ │ │ ├── IcIcon.vue │ │ │ ├── Icon.vue │ │ │ ├── Input.vue │ │ │ ├── LoadingIndicator.vue │ │ │ ├── Notification.vue │ │ │ ├── Overlay.vue │ │ │ ├── Select.vue │ │ │ ├── Switch.vue │ │ │ ├── Tooltip.vue │ │ │ └── index.ts │ │ ├── composables │ │ │ ├── index.ts │ │ │ ├── notification.ts │ │ │ ├── shiki.ts │ │ │ └── theme.ts │ │ ├── constants │ │ │ └── ic-icons.ts │ │ ├── index.ts │ │ └── types │ │ │ ├── floating-vue.ts │ │ │ └── index.ts │ ├── storybook │ │ ├── Badge.story.vue │ │ ├── Button.story.vue │ │ ├── Card.story.vue │ │ ├── Checkbox.story.vue │ │ ├── Confirm.story.vue │ │ ├── DarkToggle.story.vue │ │ ├── Dialog.story.vue │ │ ├── Drawer.story.vue │ │ ├── Dropdown.story.vue │ │ ├── FormField.story.vue │ │ ├── IcIcon.story.vue │ │ ├── Input.story.vue │ │ ├── Notification.story.vue │ │ ├── Select.story.vue │ │ ├── Switch.story.vue │ │ └── Tooltip.story.vue │ ├── theme │ │ ├── index.ts │ │ ├── theme.ts │ │ └── uno.config.ts │ ├── tsconfig.json │ ├── uno.config.ts │ └── vite.config.ts └── vite │ ├── README.md │ ├── build.config.ts │ ├── esbuild-shims │ └── cjs-shim.ts │ ├── package.json │ ├── src │ ├── dir.ts │ ├── overlay.js │ ├── rpc │ │ ├── assets.ts │ │ ├── get-config.ts │ │ ├── graph.ts │ │ ├── index.ts │ │ └── types.ts │ ├── utils.ts │ └── vite.ts │ └── tsup.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── extension-zip.ts ├── release-extension.ts └── vue-api-manifest.ts ├── tsconfig.json ├── turbo.json ├── uno.config.ts └── vitest.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | insert_final_newline = false 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [webfansplz] 2 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base", 5 | "schedule:weekly", 6 | "group:allNonMajor", 7 | ":disableDependencyDashboard" 8 | ], 9 | "ignoreDeps": [ 10 | "node", 11 | "nanoid", 12 | "vite-plugin-inspect" 13 | ], 14 | "labels": [ 15 | "dependencies" 16 | ], 17 | "packageRules": [ 18 | { 19 | "depTypeList": [ 20 | "peerDependencies" 21 | ], 22 | "enabled": false 23 | }, 24 | { 25 | "allowedVersions": "<3.0.0", 26 | "matchPackageNames": [ 27 | "estree-walker" 28 | ] 29 | } 30 | ], 31 | "pin": { 32 | "enabled": false 33 | }, 34 | "postUpdateOptions": [ 35 | "pnpmDedupe" 36 | ], 37 | "rangeStrategy": "bump" 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/autofix.yml: -------------------------------------------------------------------------------- 1 | name: autofix.ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Set node 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: lts/* 22 | 23 | - name: Install pnpm 24 | # https://github.com/nitrojs/nitro/pull/3060 25 | # https://github.com/nodejs/corepack/pull/614 26 | run: npm i -g --force corepack && corepack enable pnpm 27 | 28 | - name: Setup 29 | run: npm i -g @antfu/ni 30 | 31 | - name: Install 32 | run: nci 33 | 34 | - name: Build 35 | run: nr build 36 | 37 | - name: Lint 38 | run: nr lint --fix 39 | 40 | - uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef 41 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | ci: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Set node 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: lts/* 22 | 23 | - name: Install pnpm 24 | # https://github.com/nitrojs/nitro/pull/3060 25 | # https://github.com/nodejs/corepack/pull/614 26 | run: npm i -g --force corepack && corepack enable pnpm 27 | 28 | - name: Setup ni 29 | run: npm i -g @antfu/ni 30 | 31 | - name: Install 32 | run: nci 33 | 34 | - name: Build 35 | run: nr build 36 | 37 | - name: Lint 38 | run: nr lint 39 | 40 | - name: Test 41 | run: nr test 42 | -------------------------------------------------------------------------------- /.github/workflows/pkg.pr.new.yml: -------------------------------------------------------------------------------- 1 | name: Publish Any Commit 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - '**' 8 | tags: 9 | - '!**' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | # https://github.com/nitrojs/nitro/pull/3060 22 | # https://github.com/nodejs/corepack/pull/614 23 | - run: npm i -g --force corepack && corepack enable pnpm 24 | 25 | - name: Set node 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: lts/* 29 | cache: pnpm 30 | 31 | - name: Install 32 | run: pnpm install 33 | 34 | - name: Build 35 | run: pnpm build 36 | 37 | - name: Release 38 | run: pnpm dlx pkg-pr-new publish --compact --pnpm './packages/{core,devtools,devtools-api,devtools-kit,vite,applet}' 39 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: 20.x 22 | 23 | - run: npx changelogithub 24 | env: 25 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 26 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | lts-latest 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | side-effects-cache=false 4 | shell-emulator=true 5 | -------------------------------------------------------------------------------- /bump.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'bumpp' 2 | import fg from 'fast-glob' 3 | 4 | export default defineConfig({ 5 | files: fg.sync(['./packages/*/package.json'], { 6 | ignore: ['./packages/*-extension/package.json'], 7 | }), 8 | }) 9 | -------------------------------------------------------------------------------- /docs/.vitepress/components/Home.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /docs/.vitepress/components/HomeContributors.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /docs/.vitepress/components/HomeSponsors.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import Theme from 'vitepress/theme' 3 | import { h } from 'vue' 4 | import 'uno.css' 5 | import './style.css' 6 | 7 | export default { 8 | extends: Theme, 9 | Layout: () => { 10 | return h(Theme.Layout, null, {}) 11 | }, 12 | enhanceApp({ app }: any) { 13 | // 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /docs/.vitepress/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetIcons, 5 | presetUno, 6 | } from 'unocss' 7 | 8 | export default defineConfig({ 9 | shortcuts: { 10 | 'border-base': 'border-color-$vp-c-divider', 11 | 'text-brand': 'color-$vp-c-brand-1', 12 | 'text-brand-yellow': 'color-$vp-c-yellow-1', 13 | 'text-brand-red': 'color-$vp-c-red-1', 14 | }, 15 | blocklist: [ 16 | 'container', 17 | ], 18 | presets: [ 19 | presetUno(), 20 | presetAttributify(), 21 | presetIcons(), 22 | ], 23 | safelist: [ 24 | 'font-mono', 25 | 'mb0!', 26 | 'no-underline!', 27 | ], 28 | }) 29 | -------------------------------------------------------------------------------- /docs/.vitepress/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import UnoCSS from 'unocss/vite' 3 | import Components from 'unplugin-vue-components/vite' 4 | import { defineConfig } from 'vite' 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | Components({ 9 | dirs: [ 10 | fileURLToPath(new URL('./components', import.meta.url)), 11 | ], 12 | dts: fileURLToPath(new URL('../components.d.ts', import.meta.url)), 13 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/], 14 | extensions: ['vue', 'md'], 15 | }), 16 | UnoCSS( 17 | fileURLToPath(new URL('./uno.config.ts', import.meta.url)), 18 | ), 19 | ], 20 | }) 21 | -------------------------------------------------------------------------------- /docs/getting-started/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | There are multiple options to add this tool to your projects, ensuring that it fits seamlessly into your development workflow. Whether you're working on a [Vue.js](https://vuejs.org/) project with [Vite](https://vitejs.dev/), a standalone Vue.js application, or a web application, Vue DevTools offers a solution that match your needs: 4 | 5 | 6 | 7 | 8 | 9 | ## Notice 10 | 11 | :::warning Compatibility Note 12 | The DevTools is only compatible with Vue 3. If you are still using Vue2, use [vue-devtools](https://devtools-v6.vuejs.org/) instead. 13 | ::: 14 | 15 | :::tip Recommendation 16 | If you are using Nuxt, use [nuxt-devtools](https://github.com/nuxt/devtools) for a more powerful developer experience. 17 | ::: 18 | -------------------------------------------------------------------------------- /docs/help/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Trouble Shooting 2 | 3 | ## DevTools (vite plugin) doesn't render as expected 4 | 5 | If you see devtools render as follows: 6 | 7 | ![issue image](/screenshots/nested-issue.png) 8 | 9 | And you are using `vite-plugin-html`, please make sure register `vite-plugin-vue-devtools` before `vite-plugin-html`. 10 | 11 | ```ts 12 | // vite.config.ts 13 | import { defineConfig } from 'vite' 14 | import { createHtmlPlugin } from 'vite-plugin-html' 15 | import vueDevTools from 'vite-plugin-vue-devtools' 16 | 17 | export default defineConfig({ 18 | plugins: [ 19 | // register vueDevTools before createHtmlPlugin 20 | vueDevTools(), 21 | createHtmlPlugin({}) 22 | ] 23 | }) 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "pnpm run docs:build" 3 | publish = ".vitepress/dist" 4 | 5 | [build.environment] 6 | NODE_VERSION = "18" 7 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "version": "7.3.2", 4 | "private": true, 5 | "scripts": { 6 | "docs:build": "vitepress build", 7 | "docs:dev": "vitepress dev", 8 | "docs:preview": "vitepress preview" 9 | }, 10 | "devDependencies": { 11 | "@unocss/reset": "catalog:", 12 | "@vueuse/core": "catalog:", 13 | "unplugin-vue-components": "^28.4.1", 14 | "vitepress": "1.6.3", 15 | "vue": "catalog:" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/public/features/assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/assets.png -------------------------------------------------------------------------------- /docs/public/features/command-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/command-palette.png -------------------------------------------------------------------------------- /docs/public/features/components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/components.png -------------------------------------------------------------------------------- /docs/public/features/electron-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/electron-connection.png -------------------------------------------------------------------------------- /docs/public/features/electron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/electron.png -------------------------------------------------------------------------------- /docs/public/features/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/graph.png -------------------------------------------------------------------------------- /docs/public/features/inspect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/inspect.png -------------------------------------------------------------------------------- /docs/public/features/inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/inspector.png -------------------------------------------------------------------------------- /docs/public/features/multi-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/multi-app.png -------------------------------------------------------------------------------- /docs/public/features/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/overview.png -------------------------------------------------------------------------------- /docs/public/features/pages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/pages.png -------------------------------------------------------------------------------- /docs/public/features/pinia-timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/pinia-timeline.png -------------------------------------------------------------------------------- /docs/public/features/pinia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/pinia.png -------------------------------------------------------------------------------- /docs/public/features/router.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/router.png -------------------------------------------------------------------------------- /docs/public/features/separate-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/separate-window.png -------------------------------------------------------------------------------- /docs/public/features/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/settings.png -------------------------------------------------------------------------------- /docs/public/features/split-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/split-screen.png -------------------------------------------------------------------------------- /docs/public/features/timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/features/timeline.png -------------------------------------------------------------------------------- /docs/public/screenshots/nested-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/docs/public/screenshots/nested-issue.png -------------------------------------------------------------------------------- /eslint-plugins/index.ts: -------------------------------------------------------------------------------- 1 | import { Linter } from 'eslint' 2 | import noVueRuntime from './rules/no-vue-runtime-import' 3 | 4 | export default { 5 | rules: { 6 | 'no-vue-runtime-import': noVueRuntime, 7 | }, 8 | } satisfies Linter.FlatConfig<{ 9 | 'no-vue-runtime-import': any 10 | }> 11 | -------------------------------------------------------------------------------- /eslint-plugins/rules/no-vue-runtime-import/no-vue-runtime-import.test.ts: -------------------------------------------------------------------------------- 1 | import rule from '.' 2 | import { run } from '../../test-utils' 3 | 4 | run({ 5 | name: 'no-vue-runtime-import', 6 | rule, 7 | 8 | valid: [ 9 | 'import Vue from "abc"', 10 | 'import type { Vue } from "vue"', 11 | 'import { type bar, type baz } from "vue"', 12 | ], 13 | 14 | invalid: [ 15 | { 16 | code: 'import Vue from "vue"', 17 | errors: [{ messageId: 'no-vue-runtime-import' }], 18 | }, 19 | { 20 | code: 'import { abc } from "vue"', 21 | errors: [{ messageId: 'no-vue-runtime-import' }], 22 | }, 23 | { 24 | code: 'import * as Vue from "vue"', 25 | errors: [{ messageId: 'no-vue-runtime-import' }], 26 | }, 27 | { 28 | code: 'import { foo, type bar } from "vue"', 29 | errors: [{ messageId: 'no-vue-runtime-import' }], 30 | }, 31 | ], 32 | }) 33 | -------------------------------------------------------------------------------- /eslint-plugins/test-utils.ts: -------------------------------------------------------------------------------- 1 | import type { RuleTesterInitOptions, TestCasesOptions } from 'eslint-vitest-rule-tester' 2 | 3 | import tsParser from '@typescript-eslint/parser' 4 | import { run as _run } from 'eslint-vitest-rule-tester' 5 | 6 | export * from 'eslint-vitest-rule-tester' 7 | 8 | export { unindent as $ } from 'eslint-vitest-rule-tester' 9 | 10 | export interface ExtendedRuleTesterOptions extends RuleTesterInitOptions, TestCasesOptions { 11 | lang?: 'js' | 'ts' 12 | } 13 | 14 | export function run(options: ExtendedRuleTesterOptions) { 15 | return _run({ 16 | recursive: false, 17 | verifyAfterFix: false, 18 | ...(options.lang === 'js' ? {} : { parser: tsParser as any }), 19 | ...options, 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /eslint-plugins/utils.ts: -------------------------------------------------------------------------------- 1 | import type { TSESLint, TSESTree } from '@typescript-eslint/utils' 2 | import type { Rule } from 'eslint' 3 | 4 | export function createRule( 5 | rule: Omit, 'defaultOptions'>, 6 | ) { 7 | return rule as unknown as Rule.RuleModule 8 | } 9 | 10 | export function isTypeImport(node: TSESTree.ImportDeclaration) { 11 | return node.importKind === 'type' 12 | || node.specifiers.filter((s) => { 13 | if (s.type !== 'ImportSpecifier') 14 | return true 15 | if (s.importKind !== 'type') 16 | return true 17 | return false 18 | }).length === 0 19 | } 20 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/AppConnecting.vue: -------------------------------------------------------------------------------- 1 | 3 | 4 | 14 | 15 | 42 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/DevToolsHeader.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/Empty.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/Navbar.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 21 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/NodeTag.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 26 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/SelectiveList.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 29 | -------------------------------------------------------------------------------- /packages/applet/src/components/basic/ToggleExpanded.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /packages/applet/src/components/state/ChildStateViewer.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 26 | -------------------------------------------------------------------------------- /packages/applet/src/composables/component-highlight.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from '@vue/devtools-core' 2 | import { useDebounceFn } from '@vueuse/core' 3 | 4 | const THROTTLE_TIME = 200 5 | 6 | export function useComponentHighlight() { 7 | const highlight = useDebounceFn((id: string) => { 8 | return rpc.value.highlighComponent(id) 9 | }, THROTTLE_TIME) 10 | 11 | const unhighlight = useDebounceFn(() => { 12 | return rpc.value.unhighlight() 13 | }, THROTTLE_TIME) 14 | 15 | return { 16 | highlight, 17 | unhighlight, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/applet/src/composables/custom-inspector-state.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, Ref } from 'vue' 2 | import { inject, provide, ref } from 'vue' 3 | 4 | type CustomInspectorState = Partial<{ 5 | homepage: string 6 | id: string 7 | pluginId: string 8 | label: string 9 | logo: string 10 | timelineLayerIds: string[] 11 | treeFilterPlaceholder: string 12 | stateFilterPlaceholder: string 13 | }> 14 | 15 | const VueDevToolsStateSymbol: InjectionKey> = Symbol.for('VueDevToolsCustomInspectorStateSymbol') 16 | 17 | export function useCustomInspectorState() { 18 | return inject(VueDevToolsStateSymbol)! 19 | } 20 | 21 | export function createCustomInspectorStateContext() { 22 | const state = ref({ 23 | homepage: '', 24 | id: '', 25 | label: '', 26 | logo: '', 27 | timelineLayerIds: [], 28 | }) as Ref 29 | provide(VueDevToolsStateSymbol, state) 30 | return state 31 | } 32 | -------------------------------------------------------------------------------- /packages/applet/src/composables/hover.ts: -------------------------------------------------------------------------------- 1 | import type { MaybeRefOrGetter } from '@vueuse/core' 2 | import { useEventListener } from '@vueuse/core' 3 | import { ref } from 'vue' 4 | 5 | export interface UseHoverOptions { 6 | enter?: () => void 7 | leave?: () => void 8 | initial?: boolean 9 | } 10 | 11 | export function useHover(el: MaybeRefOrGetter, options: UseHoverOptions = {}) { 12 | const { 13 | enter = () => { }, 14 | leave = () => { }, 15 | initial = false, 16 | } = options 17 | const isHovering = ref(initial) 18 | 19 | useEventListener(el, 'mouseenter', () => { 20 | isHovering.value = true 21 | enter() 22 | }) 23 | useEventListener(el, 'mouseleave', () => { 24 | isHovering.value = false 25 | leave() 26 | }) 27 | 28 | return { 29 | isHovering, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/applet/src/composables/select.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, Ref } from 'vue' 2 | import { inject, provide, ref } from 'vue' 3 | 4 | const SelectedSymbolKey: InjectionKey> = Symbol('SelectedSymbolKey') 5 | 6 | export function createSelectedContext() { 7 | const selected = ref('') 8 | 9 | provide>(SelectedSymbolKey, selected) 10 | 11 | return { 12 | selected, 13 | } 14 | } 15 | 16 | export function useSelect() { 17 | const selected = inject>(SelectedSymbolKey, ref(''))! 18 | 19 | function select(value: string) { 20 | selected.value = value 21 | } 22 | 23 | return { 24 | selected, 25 | select, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/applet/src/composables/toggle-expanded.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue' 2 | import { inject, provide, ref } from 'vue' 3 | 4 | const expandedKey = 'expanded-state' 5 | 6 | export function createExpandedContext(id = '') { 7 | const expanded = ref([]) 8 | 9 | provide>(`${expandedKey}-${id}`, expanded) 10 | 11 | return { 12 | expanded, 13 | } 14 | } 15 | 16 | export function useToggleExpanded(id = '') { 17 | const expanded = inject>(`${expandedKey}-${id}`, ref([]))! 18 | 19 | function toggleExpanded(key: string) { 20 | const index = expanded.value.indexOf(key) 21 | if (index === -1) 22 | expanded.value.push(key) 23 | 24 | else 25 | expanded.value.splice(index, 1) 26 | } 27 | 28 | return { 29 | expanded, 30 | toggleExpanded, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/applet/src/index.ts: -------------------------------------------------------------------------------- 1 | import SelectiveList from './components/basic/SelectiveList.vue' 2 | import Timeline from './components/timeline/index.vue' 3 | import 'uno.css' 4 | import '@unocss/reset/tailwind.css' 5 | import './styles/base.css' 6 | import '@vue/devtools-ui/style.css' 7 | import '@vue/devtools-ui/uno.css' 8 | 9 | export * from './composables/custom-inspector' 10 | export * from './modules/components' 11 | export * from './modules/custom-inspector' 12 | export * from './modules/pinia' 13 | export * from './modules/router' 14 | 15 | export { 16 | SelectiveList, 17 | Timeline, 18 | } 19 | -------------------------------------------------------------------------------- /packages/applet/src/modules/components/components/RenderCode.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 26 | -------------------------------------------------------------------------------- /packages/applet/src/modules/components/index.ts: -------------------------------------------------------------------------------- 1 | import Components from './index.vue' 2 | 3 | export { 4 | Components, 5 | } 6 | -------------------------------------------------------------------------------- /packages/applet/src/modules/custom-inspector/components/timeline/Index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /packages/applet/src/modules/custom-inspector/index.ts: -------------------------------------------------------------------------------- 1 | import CustomInspector from './index.vue' 2 | 3 | export { 4 | CustomInspector, 5 | } 6 | -------------------------------------------------------------------------------- /packages/applet/src/modules/pinia/components/Settings.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 29 | -------------------------------------------------------------------------------- /packages/applet/src/modules/pinia/components/timeline/Index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /packages/applet/src/modules/pinia/constants.ts: -------------------------------------------------------------------------------- 1 | export const PiniaPluginDescriptorId = 'dev.esm.pinia' 2 | export const PiniaPluginInspectorId = 'pinia' 3 | -------------------------------------------------------------------------------- /packages/applet/src/modules/pinia/index.ts: -------------------------------------------------------------------------------- 1 | import Pinia from './index.vue' 2 | 3 | export { 4 | Pinia, 5 | } 6 | -------------------------------------------------------------------------------- /packages/applet/src/modules/router/components/timeline/Index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /packages/applet/src/modules/router/index.ts: -------------------------------------------------------------------------------- 1 | import Router from './index.vue' 2 | 3 | export { 4 | Router, 5 | } 6 | -------------------------------------------------------------------------------- /packages/applet/src/utils/color.ts: -------------------------------------------------------------------------------- 1 | export function toHex(color: number) { 2 | return color.toString(16).padStart(6, '0') 3 | } 4 | -------------------------------------------------------------------------------- /packages/applet/src/utils/date.ts: -------------------------------------------------------------------------------- 1 | export type TimeFormat = 'ms' | 'default' 2 | 3 | export function formatTime(timestamp: string | number | Date, format?: TimeFormat) { 4 | const date = new Date(timestamp) 5 | return `${date.toString().match(/\d\d:\d\d:\d\d/)![0]}${format === 'ms' ? `.${String(date.getMilliseconds()).padStart(3, '0')}` : ''}` 6 | } 7 | -------------------------------------------------------------------------------- /packages/applet/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './color' 2 | export * from './date' 3 | export * from './search' 4 | -------------------------------------------------------------------------------- /packages/applet/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "module": "esnext", 7 | "paths": { 8 | "~/*": ["./src/*"] 9 | }, 10 | "types": [ 11 | "vite/client" 12 | ], 13 | "outDir": "./dist", 14 | "skipLibCheck": true 15 | }, 16 | "include": ["src/**/*.vue", "src/**/*.d.ts", "src/**/*.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/applet/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import Vue from '@vitejs/plugin-vue' 3 | import Unocss from 'unocss/vite' 4 | import Dts from 'vite-plugin-dts' 5 | import { dependencies, peerDependencies } from './package.json' 6 | 7 | const argv = process.argv.slice(2) 8 | const enableWatch = argv.includes('--watch') 9 | 10 | export default { 11 | resolve: { 12 | alias: { 13 | '~/': `${resolve(__dirname)}/src/`, 14 | }, 15 | }, 16 | plugins: [ 17 | Unocss(), 18 | Vue(), 19 | Dts(), 20 | ], 21 | build: { 22 | emptyOutDir: !enableWatch, 23 | lib: { 24 | entry: resolve(__dirname, './src/index.ts'), 25 | name: 'devtoolsApplet', 26 | fileName: ext => `index.${ext === 'es' ? 'js' : ext}`, 27 | formats: ['es', 'cjs'], 28 | }, 29 | rollupOptions: { 30 | external: [...Object.keys(peerDependencies), ...Object.keys(dependencies)], 31 | output: { 32 | assetFileNames: 'index.[ext]', 33 | globals: { 34 | vue: 'Vue', 35 | }, 36 | }, 37 | }, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /packages/chrome-extension/README.md: -------------------------------------------------------------------------------- 1 | # Browser extension 2 | 3 | > DevTools Browser extension, still under development... 4 | -------------------------------------------------------------------------------- /packages/chrome-extension/icons/128-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/128-beta.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/128-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/128-gray.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/128.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/128.nuxt.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/128.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/128.vitepress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/128.vitepress.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/16-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/16-beta.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/16-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/16-gray.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/16.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/16.nuxt.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/16.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/16.vitepress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/16.vitepress.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/48-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/48-beta.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/48-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/48-gray.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/48.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/48.nuxt.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/48.png -------------------------------------------------------------------------------- /packages/chrome-extension/icons/48.vitepress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/icons/48.vitepress.png -------------------------------------------------------------------------------- /packages/chrome-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-chrome-extension", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "private": true, 6 | "author": "webfansplz", 7 | "license": "MIT", 8 | "files": [ 9 | "dist" 10 | ], 11 | "scripts": { 12 | "build": "cross-env NODE_ENV=production tsup", 13 | "dev": "cross-env NODE_ENV=development tsup --watch" 14 | }, 15 | "dependencies": { 16 | "@vue/devtools-core": "workspace:^", 17 | "@vue/devtools-kit": "workspace:^", 18 | "@vue/devtools-shared": "workspace:^" 19 | }, 20 | "devDependencies": { 21 | "@vitejs/plugin-vue": "catalog:", 22 | "vue": "catalog:" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/chrome-extension/pages/devtools-background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/chrome-extension/pages/devtools-panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/devtools-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/chrome-extension/popups/devtools-screenshot.png -------------------------------------------------------------------------------- /packages/chrome-extension/popups/disabled.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/disabled.nuxt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Nuxt + Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/disabled.vitepress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | VitePress + Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/enabled.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/enabled.nuxt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | Nuxt + Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/enabled.vitepress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | VitePress + Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/not-found.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Vue.js not detected 6 |

7 | -------------------------------------------------------------------------------- /packages/chrome-extension/popups/popup.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700,700i'); 2 | 3 | body { 4 | font-family: Roboto, Avenir, Helvetica, Arial, sans-serif; 5 | font-size: 14px; 6 | font-weight: 400; 7 | line-height: 1.4; 8 | padding: 18px 24px; 9 | color: #2c3e50; 10 | } 11 | 12 | body, 13 | p { 14 | margin: 0; 15 | } 16 | 17 | p { 18 | min-width: 200px; 19 | max-width: 300px; 20 | } 21 | 22 | .short-paragraph { 23 | min-width: initial; 24 | white-space: nowrap; 25 | } 26 | 27 | a { 28 | color: #42b983; 29 | } 30 | 31 | .flex { 32 | display: flex; 33 | align-items: center; 34 | } 35 | 36 | .screenshot { 37 | position: relative; 38 | } 39 | 40 | .screenshot > img { 41 | width: 140px; 42 | height: 140px; 43 | object-fit: cover; 44 | border-radius: 100%; 45 | margin-right: 24px; 46 | box-shadow: 0 0 15px rgb(0 0 0 / 10%); 47 | } 48 | 49 | .migration-guide { 50 | width: 300px; 51 | margin: 0; 52 | padding: 0; 53 | } 54 | 55 | .migration-guide h2 { 56 | padding: 8px 0; 57 | margin: 0; 58 | } 59 | -------------------------------------------------------------------------------- /packages/chrome-extension/src/devtools-overlay.ts: -------------------------------------------------------------------------------- 1 | const body = document.getElementsByTagName('body')[0] 2 | 3 | // create detector script 4 | const detector = document.createElement('script') 5 | detector.src = chrome.runtime.getURL('dist/detector.js') 6 | detector.onload = () => { 7 | detector.parentNode!.removeChild(detector) 8 | } 9 | 10 | ;(document.head || document.documentElement).appendChild(detector) 11 | 12 | window.addEventListener('message', (event) => { 13 | if (event.data.key === '__VUE_DEVTOOLS_VUE_DETECTED_EVENT__') { 14 | chrome.runtime.sendMessage(event.data.data) 15 | } 16 | }, false) 17 | -------------------------------------------------------------------------------- /packages/chrome-extension/src/prepare.ts: -------------------------------------------------------------------------------- 1 | import { devtools } from '../../devtools-kit/src/index' 2 | 3 | devtools.init() 4 | 5 | window.__VUE_DEVTOOLS_BROWSER_EXTENSION_DETECTED__ = true 6 | -------------------------------------------------------------------------------- /packages/chrome-extension/src/user-app.ts: -------------------------------------------------------------------------------- 1 | import { functions } from '@vue/devtools-core' 2 | import { createRpcServer } from '@vue/devtools-kit' 3 | 4 | window.addEventListener('message', handshake) 5 | 6 | createRpcServer(functions, { 7 | preset: 'extension', 8 | }) 9 | 10 | function handshake(e: MessageEvent) { 11 | if (e.data.source === 'proxy->server' && e.data.payload.event === 'init') { 12 | window.removeEventListener('message', handshake) 13 | 14 | const listeners: ((event: unknown) => void)[] = [] 15 | } 16 | } 17 | 18 | // window.addEventListener('message', toggleOverlay) 19 | 20 | // function toggleOverlay(e) { 21 | // const data = e.data 22 | // const payload = data.payload 23 | // if (data.source === '__VUE_DEVTOOLS_OVERLAY__' && payload.event === 'toggle-view-mode') { 24 | // // @TODO: refactor 25 | // target?.__VUE_DEVTOOLS_TOGGLE_OVERLAY__?.(payload.data === 'overlay') 26 | // } 27 | // } 28 | -------------------------------------------------------------------------------- /packages/chrome-extension/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/*.ts', 6 | ], 7 | esbuildOptions(options) { 8 | if (options.format === 'iife') 9 | options.outExtension = { '.js': '.js' } 10 | }, 11 | define: { 12 | 'process.env': JSON.stringify(process.env), 13 | '__VUE_OPTIONS_API__': 'true', 14 | '__VUE_PROD_DEVTOOLS__': 'true', 15 | }, 16 | clean: true, 17 | format: ['iife'], 18 | minify: true, 19 | }) 20 | -------------------------------------------------------------------------------- /packages/client/README.md: -------------------------------------------------------------------------------- 1 | # DevTools Client 2 | 3 | > Client for DevTools. 4 | -------------------------------------------------------------------------------- /packages/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Client 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/client/public/color-scheme.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches 3 | const setting = localStorage.getItem('color-schema') || 'auto' 4 | if (setting === 'dark' || (prefersDark && setting !== 'light')) 5 | document.documentElement.classList.toggle('dark', true) 6 | })() 7 | -------------------------------------------------------------------------------- /packages/client/scripts/pre-build.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { fileURLToPath } from 'node:url' 3 | import fse from 'fs-extra' 4 | 5 | const __dirname = fileURLToPath(new URL('.', import.meta.url)) 6 | 7 | async function run() { 8 | ;['../../chrome-extension/client', '../../electron/client', '../../vite/client'].forEach((dir) => { 9 | const absoluteDir = resolve(__dirname, dir) 10 | if (fse.existsSync(absoluteDir)) 11 | fse.removeSync(absoluteDir) 12 | }) 13 | console.log('🎉 Pre-build: removed client bundles successfully.\n') 14 | } 15 | 16 | await run() 17 | -------------------------------------------------------------------------------- /packages/client/src/components/AppConnecting.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 16 | 43 | -------------------------------------------------------------------------------- /packages/client/src/components/assets/AssetFontPreview.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /packages/client/src/components/assets/AssetGridItem.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 24 | -------------------------------------------------------------------------------- /packages/client/src/components/assets/FilepathItem.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /packages/client/src/components/chrome/ViewModeSwitch.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /packages/client/src/components/common/EmptyPane.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /packages/client/src/components/common/ExpandIcon.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /packages/client/src/components/common/IconTitle.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | -------------------------------------------------------------------------------- /packages/client/src/components/common/Navbar.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 42 | -------------------------------------------------------------------------------- /packages/client/src/components/common/PanelGrids.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/client/src/components/common/SFCView.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 30 | -------------------------------------------------------------------------------- /packages/client/src/components/common/TabsGrid.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /packages/client/src/components/pages/RouteMetaDetail.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | -------------------------------------------------------------------------------- /packages/client/src/composables/app.ts: -------------------------------------------------------------------------------- 1 | import type { AppRecord } from '@vue/devtools-kit' 2 | 3 | export const activeAppRecords = shallowRef([]) 4 | export const activeAppRecordId = ref(null) 5 | export const activeAppRecord = computed(() => activeAppRecords.value.find(r => r.id === activeAppRecordId.value)) 6 | -------------------------------------------------------------------------------- /packages/client/src/composables/custom-inspector-tabs.ts: -------------------------------------------------------------------------------- 1 | import type { CustomInspectorType } from '@vue/devtools-applet' 2 | import type { ModuleBuiltinTab } from '~/types/tab' 3 | 4 | import { useCustomInspector } from '@vue/devtools-applet' 5 | 6 | export function useCustomInspectorTabs() { 7 | const { registeredInspector } = useCustomInspector() 8 | 9 | const customInspectorTabs = computed(() => { 10 | return registeredInspector.value.map((inspector: CustomInspectorType, index) => { 11 | return { 12 | order: index, 13 | name: inspector.id, 14 | icon: inspector.logo, 15 | fallbackIcon: inspector.icon, 16 | title: inspector.label, 17 | path: `${CUSTOM_INSPECTOR_TAB_VIEW}/${inspector.id}`, 18 | category: 'modules', 19 | pluginId: inspector.pluginId, 20 | } 21 | }) 22 | }) 23 | 24 | return customInspectorTabs 25 | } 26 | -------------------------------------------------------------------------------- /packages/client/src/composables/editor.ts: -------------------------------------------------------------------------------- 1 | import { showVueNotification } from '@vue/devtools-ui' 2 | 3 | interface CopyOptions { 4 | silent?: boolean 5 | type?: string 6 | } 7 | 8 | export function useCopy() { 9 | const { copy: _copy, copied } = useClipboard() 10 | 11 | const copy = (text: string, options: CopyOptions = {}) => { 12 | const { 13 | silent = false, 14 | type = '', 15 | } = options 16 | _copy(text).then(() => { 17 | if (!silent) { 18 | showVueNotification({ 19 | message: 'Copied to clipboard', 20 | type: 'success', 21 | duration: 3000, 22 | }) 23 | } 24 | }).catch(() => { 25 | if (!silent) { 26 | showVueNotification({ 27 | message: 'Failed to copy to clipboard', 28 | type: 'error', 29 | duration: 3000, 30 | }) 31 | } 32 | }) 33 | } 34 | 35 | return { 36 | copy, 37 | copied, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/client/src/composables/host.ts: -------------------------------------------------------------------------------- 1 | import { 2 | isInChromePanel, 3 | isInElectron, 4 | isInIframe, 5 | } from '@vue/devtools-shared' 6 | 7 | export function useHostEnv() { 8 | if (isInElectron) 9 | return 'electron' 10 | 11 | else if (isInChromePanel) 12 | return 'chrome' 13 | 14 | else if (isInIframe) 15 | return 'iframe' 16 | else 17 | return 'separate-window' 18 | } 19 | -------------------------------------------------------------------------------- /packages/client/src/composables/hover.ts: -------------------------------------------------------------------------------- 1 | import type { MaybeRefOrGetter } from '@vueuse/core' 2 | import { useEventListener } from '@vueuse/core' 3 | 4 | export interface UseHoverOptions { 5 | enter?: () => void 6 | leave?: () => void 7 | initial?: boolean 8 | } 9 | 10 | export function useHover(el: MaybeRefOrGetter, options: UseHoverOptions = {}) { 11 | const { 12 | enter = () => { }, 13 | leave = () => { }, 14 | initial = false, 15 | } = options 16 | const isHovering = ref(initial) 17 | 18 | useEventListener(el, 'mouseenter', () => { 19 | isHovering.value = true 20 | enter() 21 | }) 22 | useEventListener(el, 'mouseleave', () => { 23 | isHovering.value = false 24 | leave() 25 | }) 26 | 27 | return { 28 | isHovering, 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/client/src/composables/open-in-editor.ts: -------------------------------------------------------------------------------- 1 | import { rpc } from '@vue/devtools-core' 2 | import { isInChromePanel } from '@vue/devtools-shared' 3 | 4 | export const vueInspectorDetected = ref(false) 5 | 6 | export const openInEditor = async (file: string) => { 7 | const opts: { file: string, host?: string } = { file } 8 | if (isInChromePanel) { 9 | opts.host = 'chrome-extension' 10 | } 11 | return rpc.value.openInEditor(opts) 12 | } 13 | -------------------------------------------------------------------------------- /packages/client/src/composables/view-mode.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/client/src/composables/view-mode.ts -------------------------------------------------------------------------------- /packages/client/src/index.ts: -------------------------------------------------------------------------------- 1 | export { createConnectionApp, disconnectDevToolsClient, initDevTools, reloadDevToolsClient } from './main' 2 | 3 | export function reload() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /packages/client/src/pages/components.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /packages/client/src/pages/custom-tab-view.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 27 | -------------------------------------------------------------------------------- /packages/client/src/pages/pinia.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /packages/client/src/pages/router.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 15 | -------------------------------------------------------------------------------- /packages/client/src/setup/unocss-runtime.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/client/src/setup/unocss-runtime.ts -------------------------------------------------------------------------------- /packages/client/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export type * from './tab' 2 | -------------------------------------------------------------------------------- /packages/client/src/types/tab.ts: -------------------------------------------------------------------------------- 1 | import type { CustomTab } from '@vue/devtools-kit' 2 | import type { MaybeRefOrGetter } from 'vue' 3 | 4 | export interface ModuleBuiltinTab extends Pick { 5 | fallbackIcon?: string 6 | order?: number 7 | path: string 8 | show?: () => MaybeRefOrGetter 9 | badge?: () => MaybeRefOrGetter 10 | onClick?: () => void 11 | } 12 | -------------------------------------------------------------------------------- /packages/client/src/utils/color.ts: -------------------------------------------------------------------------------- 1 | import { colord } from 'colord' 2 | 3 | export function toHex(color: number) { 4 | return color.toString(16).padStart(6, '0') 5 | } 6 | 7 | export function dimColor(color: number, isDark: boolean, amount = 20) { 8 | let c = colord(toHex(color)) 9 | if (isDark) 10 | c = c.darken(amount) 11 | 12 | else 13 | c = c.lighten(amount) 14 | 15 | return Number.parseInt(`0x${c.toHex().slice(1)}`) 16 | } 17 | 18 | export function boostColor(color: number, isDark: boolean, amount = 10) { 19 | let c = colord(toHex(color)) 20 | if (isDark) 21 | c = c.lighten(amount) 22 | 23 | else 24 | c = c.darken(amount) 25 | 26 | return Number.parseInt(`0x${c.toHex().slice(1)}`) 27 | } 28 | -------------------------------------------------------------------------------- /packages/client/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './color' 2 | export * from './time' 3 | -------------------------------------------------------------------------------- /packages/client/src/utils/time.ts: -------------------------------------------------------------------------------- 1 | export type TimeFormat = 'ms' | 'default' 2 | 3 | export function formatTime(timestamp: string | number | Date, format?: TimeFormat) { 4 | const date = new Date(timestamp) 5 | return `${date.toString().match(/\d\d:\d\d:\d\d/)![0]}${format === 'ms' ? `.${String(date.getMilliseconds()).padStart(3, '0')}` : ''}` 6 | } 7 | -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "module": "esnext", 7 | "paths": { 8 | "~/*": ["./src/*"] 9 | }, 10 | "types": [ 11 | "vite/client" 12 | ] 13 | }, 14 | "include": ["**/*.ts", "**/*.d.ts", "**/*.vue"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/client/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { relative, resolve } from 'node:path' 2 | import fse from 'fs-extra' 3 | import { defineConfig, mergeConfig } from 'vite' 4 | import baseConfig from './vite.base.config' 5 | 6 | export default defineConfig(mergeConfig(baseConfig, { 7 | base: './', 8 | plugins: [ 9 | { 10 | name: 'vite-plugin-copy-devtools-client-bundle', 11 | apply: 'build', 12 | enforce: 'post', 13 | closeBundle() { 14 | // copy 15 | const clientFile = resolve(__dirname, './dist') 16 | 17 | ;['../vite/client'].forEach((dir) => { 18 | fse.copySync(clientFile, resolve(__dirname, dir), { filter: (src) => { 19 | const relativePath = relative(clientFile, src) 20 | return !relativePath.includes('devtools-client-lib') 21 | } }) 22 | }) 23 | }, 24 | }, 25 | ], 26 | optimizeDeps: { 27 | exclude: [ 28 | 'vite-hot-client', 29 | ], 30 | }, 31 | build: { 32 | target: 'esnext', 33 | minify: true, // 'esbuild', 34 | emptyOutDir: true, 35 | }, 36 | })) 37 | -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools-core 2 | 3 | > Internal core functions shared across @vue/devtools packages. 4 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-core", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "author": "webfansplz", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/core", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "require": "./dist/index.cjs" 16 | } 17 | }, 18 | "main": "./dist/index.cjs", 19 | "module": "./dist/index.js", 20 | "files": [ 21 | "dist", 22 | "server.d.ts" 23 | ], 24 | "scripts": { 25 | "build": "tsup --clean", 26 | "prepare:type": "tsup --dts-only", 27 | "stub": "tsup --watch --onSuccess 'tsup --dts-only'" 28 | }, 29 | "peerDependencies": { 30 | "vue": "^3.0.0" 31 | }, 32 | "dependencies": { 33 | "@vue/devtools-kit": "workspace:^", 34 | "@vue/devtools-shared": "workspace:^", 35 | "mitt": "catalog:", 36 | "nanoid": "^5.1.0", 37 | "pathe": "catalog:", 38 | "vite-hot-client": "catalog:" 39 | }, 40 | "devDependencies": { 41 | "vue": "catalog:" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/core/src/client.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser, target } from '@vue/devtools-shared' 2 | 3 | export function setDevToolsClientUrl(url: string) { 4 | target.__VUE_DEVTOOLS_CLIENT_URL__ = url 5 | } 6 | 7 | export function getDevToolsClientUrl() { 8 | return target.__VUE_DEVTOOLS_CLIENT_URL__ ?? (() => { 9 | if (isBrowser) { 10 | const devtoolsMeta = document.querySelector('meta[name=__VUE_DEVTOOLS_CLIENT_URL__]') 11 | if (devtoolsMeta) 12 | return devtoolsMeta.getAttribute('content') 13 | } 14 | return '' 15 | })() 16 | } 17 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './rpc' 3 | export * from './vue-plugin/devtools-state' 4 | -------------------------------------------------------------------------------- /packages/core/src/rpc/index.ts: -------------------------------------------------------------------------------- 1 | export * from './global' 2 | export * from './types' 3 | export * from './vite' 4 | -------------------------------------------------------------------------------- /packages/core/src/rpc/types.ts: -------------------------------------------------------------------------------- 1 | import type { ModuleNode } from 'vite' 2 | 3 | // assets 4 | export type AssetType = 'image' | 'font' | 'video' | 'audio' | 'text' | 'json' | 'wasm' | 'other' 5 | export interface AssetInfo { 6 | path: string 7 | type: AssetType 8 | publicPath: string 9 | relativePath: string 10 | filePath: string 11 | size: number 12 | mtime: number 13 | } 14 | export interface ImageMeta { 15 | width: number 16 | height: number 17 | orientation?: number 18 | type?: string 19 | mimeType?: string 20 | } 21 | 22 | export type AssetImporter = Pick 23 | 24 | export interface AssetEntry { 25 | path: string 26 | content: string 27 | encoding?: BufferEncoding 28 | override?: boolean 29 | } 30 | 31 | export interface CodeSnippet { 32 | code: string 33 | lang: string 34 | name: string 35 | docs?: string 36 | } 37 | 38 | // graph 39 | export interface ModuleInfo { 40 | id: string 41 | plugins: { name: string, transform?: number, resolveId?: number }[] 42 | deps: string[] 43 | virtual: boolean 44 | } 45 | -------------------------------------------------------------------------------- /packages/core/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/index.ts', 6 | ], 7 | external: [ 8 | 'vue', 9 | ], 10 | noExternal: [ 11 | 'vite-hot-client', 12 | ], 13 | // clean: true, 14 | format: ['esm', 'cjs'], 15 | dts: true, 16 | shims: true, 17 | }) 18 | -------------------------------------------------------------------------------- /packages/devtools-api/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools-api 2 | 3 | > Plugins API for easier DevTools integrations. 4 | 5 | ## Getting Started 6 | 7 | Please follow the documentation at [devtools.vuejs.org](https://devtools.vuejs.org/plugins/api). 8 | -------------------------------------------------------------------------------- /packages/devtools-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-api", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "author": "webfansplz", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/devtools-api", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "sideEffects": false, 13 | "exports": { 14 | ".": { 15 | "import": "./dist/index.js", 16 | "require": "./dist/index.cjs" 17 | } 18 | }, 19 | "main": "./dist/index.cjs", 20 | "module": "./dist/index.js", 21 | "files": [ 22 | "dist" 23 | ], 24 | "scripts": { 25 | "build": "tsup --clean", 26 | "prepare:type": "tsup --dts-only", 27 | "stub": "tsup --watch --onSuccess 'tsup --dts-only'" 28 | }, 29 | "dependencies": { 30 | "@vue/devtools-kit": "workspace:^" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/devtools-api/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | addCustomCommand, 3 | addCustomTab, 4 | onDevToolsClientConnected, 5 | onDevToolsConnected, 6 | removeCustomCommand, 7 | setupDevToolsPlugin, 8 | // compatible with v6.x 9 | setupDevToolsPlugin as setupDevtoolsPlugin, 10 | } from '@vue/devtools-kit' 11 | 12 | export type { 13 | CustomCommand, 14 | CustomTab, 15 | } from '@vue/devtools-kit' 16 | -------------------------------------------------------------------------------- /packages/devtools-api/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/index.ts', 6 | ], 7 | external: [ 8 | 'vue', 9 | ], 10 | clean: true, 11 | format: ['esm', 'cjs'], 12 | dts: true, 13 | shims: true, 14 | }) 15 | -------------------------------------------------------------------------------- /packages/devtools-kit/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools-kit 2 | 3 | > Utility kit for DevTools. 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/__tests__/fixtures/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /packages/devtools-kit/__tests__/fixtures/components/Name.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/devtools-kit/global.d.ts: -------------------------------------------------------------------------------- 1 | import type { DevToolsHook, RouterInfo } from './src/types' 2 | 3 | /* eslint-disable vars-on-top, no-var */ 4 | declare global { 5 | var __VUE_DEVTOOLS_GLOBAL_HOOK__: DevToolsHook 6 | var __VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__: { 7 | id: number 8 | appIds: Set 9 | } 10 | var __VUE_DEVTOOLS_ROUTER_INFO__: RouterInfo 11 | var __VUE_DEVTOOLS_ENV__: { 12 | vitePluginDetected: boolean 13 | } 14 | var __VUE_DEVTOOLS_COMPONENT_INSPECTOR_ENABLED__: boolean 15 | var __VUE_DEVTOOLS_VITE_PLUGIN_DETECTED__: boolean 16 | var __VUE_DEVTOOLS_VITE_PLUGIN_CLIENT_URL__: string 17 | var __VUE_DEVTOOLS_BROWSER_EXTENSION_DETECTED__: boolean 18 | } 19 | 20 | export { } 21 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/api/index.ts: -------------------------------------------------------------------------------- 1 | import { DevToolsV6PluginAPI } from './v6' 2 | 3 | export const DevToolsPluginAPI = DevToolsV6PluginAPI 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/api/v7/index.ts: -------------------------------------------------------------------------------- 1 | // @TODO 2 | export class DevToolsPluginAPI { 3 | constructor() { 4 | 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/compat/index.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | 3 | // devtools <= 6.x 4 | export function isLegacyVueDevTools() { 5 | return +(target.__VUE_DEVTOOLS_GLOBAL_HOOK__.devtoolsVersion?.[0] ?? 0) < 7 6 | } 7 | 8 | export function onLegacyDevToolsPluginApiAvailable(cb: () => void) { 9 | if (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__) { 10 | cb() 11 | return 12 | } 13 | // eslint-disable-next-line accessor-pairs 14 | Object.defineProperty(target, '__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__', { 15 | set(value) { 16 | if (value) 17 | cb() 18 | }, 19 | configurable: true, 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component-highlighter/types.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentBoundingRect } from '../component/types' 2 | 3 | export interface ComponentHighLighterOptions { 4 | bounds: ComponentBoundingRect 5 | name?: string 6 | id?: string 7 | visible?: boolean 8 | } 9 | 10 | export interface ScrollToComponentOptions { 11 | id?: string 12 | } 13 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/state/index.ts: -------------------------------------------------------------------------------- 1 | import { activeAppRecord } from '../../../ctx' 2 | import { getComponentInstance, getInstanceName, getUniqueComponentId } from '../utils' 3 | import { processInstanceState } from './process' 4 | 5 | export function getInstanceState(params: { instanceId: string }) { 6 | const instance = getComponentInstance(activeAppRecord.value, params.instanceId) 7 | const id = getUniqueComponentId(instance!) 8 | const name = getInstanceName(instance!) 9 | const file = instance?.type?.__file 10 | 11 | const state = processInstanceState(instance!) 12 | return { 13 | id, 14 | name, 15 | file, 16 | state, 17 | instance, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/state/is.ts: -------------------------------------------------------------------------------- 1 | import { ensurePropertyExists } from '../utils' 2 | 3 | export function isVueInstance(value: any) { 4 | if (!ensurePropertyExists(value, '_')) { 5 | return false 6 | } 7 | if (!isPlainObject(value._)) { 8 | return false 9 | } 10 | return Object.keys(value._).includes('vnode') 11 | } 12 | 13 | export function isPlainObject(obj: unknown): obj is object { 14 | return Object.prototype.toString.call(obj) === '[object Object]' 15 | } 16 | 17 | export function isPrimitive(data: unknown) { 18 | if (data == null) 19 | return true 20 | 21 | const type = typeof data 22 | return ( 23 | type === 'string' 24 | || type === 'number' 25 | || type === 'boolean' 26 | ) 27 | } 28 | 29 | export function isRef(raw): boolean { 30 | return !!raw.__v_isRef 31 | } 32 | 33 | export function isComputed(raw): boolean { 34 | return isRef(raw) && !!raw.effect 35 | } 36 | 37 | export function isReactive(raw): boolean { 38 | return !!raw.__v_isReactive 39 | } 40 | 41 | export function isReadOnly(raw): boolean { 42 | return !!raw.__v_isReadonly 43 | } 44 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/tree/el.ts: -------------------------------------------------------------------------------- 1 | import type { VNode } from 'vue' 2 | import type { VueAppInstance } from '../../../types' 3 | import { isFragment } from '../utils' 4 | 5 | export function getRootElementsFromComponentInstance(instance: VueAppInstance): VNode[] { 6 | if (isFragment(instance)) 7 | return getFragmentRootElements(instance.subTree) 8 | 9 | if (!instance.subTree) 10 | return [] 11 | return [instance.subTree.el] as VNode[] 12 | } 13 | 14 | function getFragmentRootElements(vnode: VNode): VNode[] { 15 | if (!vnode.children) 16 | return [] 17 | 18 | const list: VNode[] = [] 19 | 20 | ;(vnode.children as VNode[]).forEach((childVnode) => { 21 | if (childVnode.component) 22 | list.push(...getRootElementsFromComponentInstance(childVnode.component as VueAppInstance)) 23 | 24 | else if (childVnode?.el) 25 | list.push(childVnode.el as VNode) 26 | }) 27 | 28 | return list 29 | } 30 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/tree/filter.ts: -------------------------------------------------------------------------------- 1 | import type { VueAppInstance } from '../../../types' 2 | import { classify, kebabize } from '@vue/devtools-shared' 3 | import { getInstanceName } from '../utils' 4 | 5 | export class ComponentFilter { 6 | filter: string 7 | 8 | constructor(filter: string) { 9 | this.filter = filter || '' 10 | } 11 | 12 | /** 13 | * Check if an instance is qualified. 14 | * 15 | * @param {Vue|Vnode} instance 16 | * @return {boolean} 17 | */ 18 | isQualified(instance: VueAppInstance): boolean { 19 | const name = getInstanceName(instance) 20 | return classify(name).toLowerCase().includes(this.filter) 21 | || kebabize(name).toLowerCase().includes(this.filter) 22 | } 23 | } 24 | 25 | export function createComponentFilter(filterText: string) { 26 | return new ComponentFilter(filterText) 27 | } 28 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/tree/index.ts: -------------------------------------------------------------------------------- 1 | import type { AppRecord } from '../../../types' 2 | import { activeAppRecord } from '../../../ctx' 3 | import { getComponentInstance } from '../utils' 4 | import { ComponentWalker } from './walker' 5 | 6 | export async function getComponentTree(options: { appRecord?: AppRecord, instanceId?: string, filterText?: string, maxDepth?: number, recursively?: boolean }) { 7 | const { appRecord = activeAppRecord.value, maxDepth = 100, instanceId = undefined, filterText = '', recursively = false } = options 8 | const instance = getComponentInstance(appRecord!, instanceId) 9 | if (instance) { 10 | const walker = new ComponentWalker({ 11 | filterText, 12 | maxDepth, 13 | recursively, 14 | }) 15 | return await walker.getComponentTree(instance) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/types/bounding-rect.ts: -------------------------------------------------------------------------------- 1 | import type { VueAppInstance } from '../../../types' 2 | 3 | export interface ComponentBoundingRect { 4 | left: number 5 | top: number 6 | right: number 7 | bottom: number 8 | width: number 9 | height: number 10 | } 11 | 12 | export interface ComponentBoundingRectApiPayload { 13 | app?: VueAppInstance 14 | inspectorId?: string 15 | instanceId?: string 16 | rect?: ComponentBoundingRect 17 | } 18 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/types/custom.ts: -------------------------------------------------------------------------------- 1 | export type customTypeEnums = 'function' | 'bigint' | 'map' | 'set' | 'store' | 'router' | 'component' | 'component-definition' | 'HTMLElement' | 'component-definition' | 'date' 2 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/types/editor.ts: -------------------------------------------------------------------------------- 1 | import type { AppRecord } from '../../../types' 2 | import type { Recordable } from '../state/editor' 3 | 4 | export type PropPath = string | string[] 5 | 6 | export interface InspectorStateEditorPayload { 7 | app?: AppRecord['app'] 8 | inspectorId: string 9 | nodeId: string 10 | type: string // reactive, ref, computed...... 11 | path: PropPath 12 | state: { 13 | value: unknown 14 | newKey: string 15 | remove?: boolean 16 | type: string // typeof something... 17 | } 18 | set?: ( 19 | obj: Recordable, 20 | path: PropPath, 21 | value: unknown, 22 | cb?: (object: Recordable, field: string, value: unknown) => void 23 | ) => unknown 24 | } 25 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bounding-rect' 2 | export * from './custom' 3 | export * from './editor' 4 | export * from './state' 5 | export * from './tree' 6 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/component/types/tree.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentTreeNode, InspectorNodeTag, VueAppInstance } from '../../../types' 2 | 3 | export interface InspectorTreeApiPayload { 4 | app?: VueAppInstance 5 | inspectorId?: string 6 | filter?: string 7 | instanceId?: string 8 | rootNodes?: ComponentTreeNode[] 9 | } 10 | 11 | export interface InspectorTree { 12 | id: string 13 | label: string 14 | tags?: InspectorNodeTag[] 15 | children?: InspectorTree[] 16 | } 17 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/devtools-client/detected.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | import { devtoolsState } from '../../ctx/state' 3 | import { toggleHighPerfMode } from '../high-perf-mode' 4 | 5 | export function updateDevToolsClientDetected(params: Record) { 6 | devtoolsState.devtoolsClientDetected = { 7 | ...devtoolsState.devtoolsClientDetected, 8 | ...params, 9 | } 10 | const devtoolsClientVisible = Object.values(devtoolsState.devtoolsClientDetected).some(Boolean) 11 | toggleHighPerfMode(!devtoolsClientVisible) 12 | } 13 | 14 | target.__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__ ??= updateDevToolsClientDetected 15 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/high-perf-mode/index.ts: -------------------------------------------------------------------------------- 1 | import { activeAppRecord, devtoolsState } from '../../ctx/state' 2 | import { registerDevToolsPlugin } from '../plugin' 3 | 4 | export function toggleHighPerfMode(state?: boolean) { 5 | devtoolsState.highPerfModeEnabled = state ?? !devtoolsState.highPerfModeEnabled 6 | if (!state && activeAppRecord.value) { 7 | registerDevToolsPlugin(activeAppRecord.value.app) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/core/vm/index.ts: -------------------------------------------------------------------------------- 1 | const MAX_$VM = 10 2 | const $vmQueue: any[] = [] 3 | 4 | // Expose instance data to window 5 | // Copied from https://github.com/vuejs/devtools/blob/f03590025b0b4910cf539531c91384be51a8f8fa/packages/app-backend-core/src/component.ts#L57-L72 6 | export function exposeInstanceToWindow(componentInstance: any) { 7 | if (typeof window === 'undefined') 8 | return 9 | const win = window as any 10 | 11 | if (!componentInstance) 12 | return 13 | 14 | win.$vm = componentInstance 15 | 16 | // $vm0, $vm1, $vm2, ... 17 | if ($vmQueue[0] !== componentInstance) { 18 | if ($vmQueue.length >= MAX_$VM) { 19 | $vmQueue.pop() 20 | } 21 | for (let i = $vmQueue.length; i > 0; i--) { 22 | win[`$vm${i}`] = $vmQueue[i] = $vmQueue[i - 1] 23 | } 24 | win.$vm0 = $vmQueue[0] = componentInstance 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/ctx/env.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | 3 | target.__VUE_DEVTOOLS_ENV__ ??= { 4 | vitePluginDetected: false, 5 | } 6 | 7 | export function getDevToolsEnv() { 8 | return target.__VUE_DEVTOOLS_ENV__ 9 | } 10 | 11 | export function setDevToolsEnv(env: Partial) { 12 | target.__VUE_DEVTOOLS_ENV__ = { 13 | ...target.__VUE_DEVTOOLS_ENV__, 14 | ...env, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/ctx/plugin.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | import { PluginDescriptor, PluginSetupFunction } from '../types' 3 | 4 | type DevToolsKitPluginBuffer = [PluginDescriptor, PluginSetupFunction] 5 | target.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__ ??= [] 6 | 7 | export const devtoolsPluginBuffer = new Proxy(target.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__, { 8 | get(target, prop, receiver) { 9 | return Reflect.get(target, prop, receiver) 10 | }, 11 | }) 12 | export function addDevToolsPluginToBuffer(pluginDescriptor: PluginDescriptor, setupFn: PluginSetupFunction) { 13 | devtoolsPluginBuffer.push([pluginDescriptor, setupFn]) 14 | } 15 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/ctx/router.ts: -------------------------------------------------------------------------------- 1 | import { target as global } from '@vue/devtools-shared' 2 | import { Router, RouterInfo } from '../types' 3 | 4 | export const ROUTER_KEY = '__VUE_DEVTOOLS_ROUTER__' 5 | export const ROUTER_INFO_KEY = '__VUE_DEVTOOLS_ROUTER_INFO__' 6 | 7 | global[ROUTER_INFO_KEY] ??= { 8 | currentRoute: null, 9 | routes: [], 10 | } 11 | 12 | global[ROUTER_KEY] ??= {} 13 | 14 | export const devtoolsRouterInfo = new Proxy(global[ROUTER_INFO_KEY], { 15 | get(target, property) { 16 | return global[ROUTER_INFO_KEY][property] 17 | }, 18 | }) 19 | 20 | export const devtoolsRouter = new Proxy<{ value: Router }>(global[ROUTER_KEY], { 21 | get(target, property) { 22 | if (property === 'value') { 23 | return global[ROUTER_KEY] 24 | } 25 | }, 26 | }) 27 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/broadcast-channel/context.ts: -------------------------------------------------------------------------------- 1 | export const __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY = '__devtools-kit-broadcast-messaging-event-key__' 2 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/broadcast-channel/index.ts: -------------------------------------------------------------------------------- 1 | import SuperJSON from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY } from './context' 4 | 5 | const BROADCAST_CHANNEL_NAME = '__devtools-kit:broadcast-channel__' 6 | 7 | export function createBroadcastChannel(): MergeableChannelOptions { 8 | const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME) 9 | 10 | return { 11 | post: (data) => { 12 | channel.postMessage(SuperJSON.stringify({ 13 | event: __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY, 14 | data, 15 | })) 16 | }, 17 | on: (handler) => { 18 | channel.onmessage = (event) => { 19 | const parsed = SuperJSON.parse<{ event: string, data: unknown }>(event.data) 20 | if (parsed.event === __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY) { 21 | handler(parsed.data) 22 | } 23 | } 24 | }, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/electron/client.ts: -------------------------------------------------------------------------------- 1 | import { SuperJSON } from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__, getElectronClientContext } from './context' 4 | 5 | export function createElectronClientChannel(): MergeableChannelOptions { 6 | const socket = getElectronClientContext() 7 | return { 8 | post: (data) => { 9 | socket.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.CLIENT_TO_PROXY, SuperJSON.stringify(data)) 10 | }, 11 | on: (handler) => { 12 | socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_CLIENT, (e) => { 13 | handler(SuperJSON.parse(e)) 14 | }) 15 | }, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/electron/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './context' 3 | export * from './proxy' 4 | export * from './server' 5 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/electron/proxy.ts: -------------------------------------------------------------------------------- 1 | import { MergeableChannelOptions } from '../../types' 2 | import { __DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__, getElectronProxyContext } from './context' 3 | 4 | export function createElectronProxyChannel(): MergeableChannelOptions { 5 | const socket = getElectronProxyContext() 6 | return { 7 | post: (data) => { 8 | }, 9 | on: (handler) => { 10 | socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY, (data) => { 11 | // @ts-expect-error skip type check 12 | socket.broadcast.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_CLIENT, data) 13 | }) 14 | 15 | socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.CLIENT_TO_PROXY, (data) => { 16 | // @ts-expect-error skip type check 17 | socket.broadcast.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER, data) 18 | }) 19 | }, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/electron/server.ts: -------------------------------------------------------------------------------- 1 | import { SuperJSON } from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__, getElectronServerContext } from './context' 4 | 5 | export function createElectronServerChannel(): MergeableChannelOptions { 6 | const socket = getElectronServerContext() 7 | return { 8 | post: (data) => { 9 | socket.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY, SuperJSON.stringify(data)) 10 | }, 11 | on: (handler) => { 12 | socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER, (data) => { 13 | handler(SuperJSON.parse(data)) 14 | }) 15 | }, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/extension/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './context' 3 | export * from './proxy' 4 | export * from './server' 5 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/extension/server.ts: -------------------------------------------------------------------------------- 1 | import { SuperJSON } from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__ } from './context' 4 | 5 | export function createExtensionServerChannel(): MergeableChannelOptions { 6 | return { 7 | post: (data) => { 8 | window.postMessage({ 9 | source: __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY, 10 | payload: SuperJSON.stringify(data), 11 | }, '*') 12 | }, 13 | on: (handler) => { 14 | const listener = (event: MessageEvent) => { 15 | if (event.data.source === __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER && event.data.payload) { 16 | handler(SuperJSON.parse(event.data.payload)) 17 | } 18 | } 19 | window.addEventListener('message', listener) 20 | return () => { 21 | window.removeEventListener('message', listener) 22 | } 23 | }, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/iframe/client.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '@vue/devtools-shared' 2 | import SuperJSON from 'superjson' 3 | import { MergeableChannelOptions } from '../../types' 4 | import { __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY } from './context' 5 | 6 | export function createIframeClientChannel(): MergeableChannelOptions { 7 | if (!isBrowser) { 8 | return { 9 | post: (data) => {}, 10 | on: (handler) => {}, 11 | } 12 | } 13 | 14 | return { 15 | post: data => window.parent.postMessage(SuperJSON.stringify({ 16 | event: __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY, 17 | data, 18 | }), '*'), 19 | on: handler => window.addEventListener('message', (event) => { 20 | try { 21 | const parsed = SuperJSON.parse<{ event: string, data: unknown }>(event.data) 22 | if (event.source === window.parent && parsed.event === __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) { 23 | handler(parsed.data) 24 | } 25 | } 26 | catch (e) { 27 | 28 | } 29 | }), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/iframe/context.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | 3 | export const __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY = '__devtools-kit-iframe-messaging-event-key__' 4 | 5 | export const __IFRAME_SERVER_CONTEXT__ = 'iframe:server-context' 6 | export function getIframeServerContext(): HTMLIFrameElement { 7 | return target[__IFRAME_SERVER_CONTEXT__] 8 | } 9 | 10 | export function setIframeServerContext(context: HTMLIFrameElement) { 11 | target[__IFRAME_SERVER_CONTEXT__] = context 12 | } 13 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/iframe/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './context' 3 | export * from './server' 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './broadcast-channel' 2 | export * from './electron' 3 | export * from './extension' 4 | export * from './iframe' 5 | export * from './vite' 6 | export * from './ws' 7 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/vite/client.ts: -------------------------------------------------------------------------------- 1 | import SuperJSON from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, getViteClientContext } from './context' 4 | 5 | export function createViteClientChannel(): MergeableChannelOptions { 6 | const client = getViteClientContext() 7 | return { 8 | post: (data) => { 9 | client?.send(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, SuperJSON.stringify(data)) 10 | }, 11 | on: (handler) => { 12 | client?.on(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, (event) => { 13 | handler(SuperJSON.parse(event)) 14 | }) 15 | }, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/vite/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './context' 3 | export * from './server' 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/vite/server.ts: -------------------------------------------------------------------------------- 1 | import SuperJSON from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { __DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, getViteServerContext } from './context' 4 | 5 | export function createViteServerChannel(): MergeableChannelOptions { 6 | const viteServer = getViteServerContext() 7 | // `server.hot` (Vite 5.1+) > `server.ws` 8 | const ws = viteServer.hot ?? viteServer.ws 9 | 10 | return { 11 | post: data => ws?.send(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, SuperJSON.stringify(data)), 12 | on: handler => ws?.on(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, (event) => { 13 | handler(SuperJSON.parse(event)) 14 | }), 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/ws/client.ts: -------------------------------------------------------------------------------- 1 | import SuperJSON from 'superjson' 2 | import { MergeableChannelOptions } from '../../types' 3 | import { getWSClientContext } from './context' 4 | 5 | export function createWSClientChannel(): MergeableChannelOptions { 6 | const ws = getWSClientContext() 7 | return { 8 | post: (data) => { 9 | data = SuperJSON.stringify(data) 10 | if (ws.readyState === WebSocket.OPEN) { 11 | ws.send(data) 12 | } 13 | else { 14 | const handle = () => { 15 | ws.send(data) 16 | ws.removeEventListener('open', handle) 17 | } 18 | ws.addEventListener('open', handle) 19 | } 20 | }, 21 | on: handler => ws.addEventListener('message', (event) => { 22 | handler(SuperJSON.parse(event.data)) 23 | }), 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/ws/context.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | 3 | interface EventEmitter { 4 | on: (name: string, handler: (data: any) => void) => void 5 | send: (name: string, ...args: any[]) => void 6 | } 7 | type WSClientContext = WebSocket 8 | interface WSServerContext extends EventEmitter {} 9 | 10 | export const __DEVTOOLS_KIT_WS_MESSAGING_EVENT_KEY = '__devtools-kit-ws-messaging-event-key__' 11 | export const __WS_CLIENT_CONTEXT__ = 'ws:client-context' 12 | export const __WS_SERVER_CONTEXT__ = 'ws:server-context' 13 | 14 | export function getWSClientContext(): WSClientContext { 15 | return target[__WS_CLIENT_CONTEXT__] 16 | } 17 | 18 | export function setWSClientContext(context: WSClientContext) { 19 | target[__WS_CLIENT_CONTEXT__] = context 20 | } 21 | 22 | export function getWSServerContext(): WSServerContext { 23 | return target[__WS_SERVER_CONTEXT__] 24 | } 25 | 26 | export function setWSServerContext(context: WSServerContext) { 27 | target[__WS_SERVER_CONTEXT__] = context 28 | } 29 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/ws/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client' 2 | export * from './context' 3 | export * from './server' 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/presets/ws/server.ts: -------------------------------------------------------------------------------- 1 | import SuperJSON from 'superjson' 2 | 3 | import { MergeableChannelOptions } from '../../types' 4 | import { getWSServerContext } from './context' 5 | 6 | export function createWSServerChannel(): MergeableChannelOptions { 7 | const ws = getWSServerContext() 8 | return { 9 | post: data => ws.send(SuperJSON.stringify(data)), 10 | on: handler => ws.on('message', (data) => { 11 | handler(SuperJSON.parse(data.toString())) 12 | }), 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/types/channel.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/devtools-kit/src/messaging/types/channel.ts -------------------------------------------------------------------------------- /packages/devtools-kit/src/messaging/types/index.ts: -------------------------------------------------------------------------------- 1 | import type { ChannelOptions } from 'birpc' 2 | 3 | export type MergeableChannelOptions = Omit 4 | 5 | export type Channel = MergeableChannelOptions | { 6 | channels: MergeableChannelOptions[] 7 | } 8 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/shared/__test__/__snapshots__/transfer.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`encode 1`] = `" [{"_":1,"__isVue":23,"a":24,"b":25},{"ctx":2,"vnode":4,"type":14,"appContext":16,"setupState":18,"attrs":19,"provides":20,"injects":21,"refs":22},{"props":3},{},[5],{"_custom":6},{"type":7,"id":8,"displayText":9,"tooltipText":10,"value":11,"fields":12},"component","__vue_devtool_undefined__","Anonymous Component","Component instance","__vue_devtool_undefined__",{"abstract":13},true,{"props":15},[],{"mixins":17},[],{},{},{},{},{},true,1,{"state":26},[27,31],{"type":28,"key":29,"value":30},"provided","$currentInstance","[[CircularRef]] ",{"type":32,"key":33,"value":34},"provided","$currentInstance2","[[CircularRef]] "]"`; 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/shared/env.ts: -------------------------------------------------------------------------------- 1 | export * from '../core/component/state/constants' 2 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './env' 2 | export * from './time' 3 | export * from './util' 4 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/shared/time.ts: -------------------------------------------------------------------------------- 1 | // import { target } from '@vue/devtools-shared' 2 | 3 | export function now() { 4 | // if (target.performance) 5 | // return target.performance.now() 6 | // else if (target.perf_hooks.performance) 7 | // return target.perf_hooks.performance.now() 8 | 9 | // else 10 | return Date.now() 11 | } 12 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/shared/util.ts: -------------------------------------------------------------------------------- 1 | import { stringifyReplacer } from '../core/component/state/replacer' 2 | import { reviver } from '../core/component/state/reviver' 3 | import { parseCircularAutoChunks, stringifyCircularAutoChunks } from './transfer' 4 | 5 | export function stringify>(data: T) { 6 | return stringifyCircularAutoChunks(data as Record, stringifyReplacer) 7 | } 8 | 9 | export function parse(data: string, revive = false) { 10 | // eslint-disable-next-line eqeqeq 11 | if (data == undefined) 12 | return {} 13 | 14 | return revive 15 | ? parseCircularAutoChunks(data, reviver) 16 | : parseCircularAutoChunks(data) 17 | } 18 | 19 | export * from '../core/component/state/format' 20 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/types/command.ts: -------------------------------------------------------------------------------- 1 | export interface CustomCommandAction { 2 | type: 'url' 3 | /** 4 | * Url of the action, if set, execute the action will open the url 5 | */ 6 | src: string 7 | } 8 | 9 | export interface CustomCommand { 10 | /** 11 | * The id of the command, should be unique 12 | */ 13 | id: string 14 | title: string 15 | description?: string 16 | /** 17 | * Order of the command, bigger number will be shown first 18 | * @default 0 19 | */ 20 | order?: number 21 | /** 22 | * Icon of the tab, support any Iconify icons, or a url to an image 23 | */ 24 | icon?: string 25 | /** 26 | * - action of the command 27 | * - __NOTE__: This will be ignored if `children` is set 28 | */ 29 | action?: CustomCommandAction 30 | /** 31 | * - children of action, if set, execute the action will show the children 32 | */ 33 | children?: Omit[] 34 | } 35 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './app' 2 | export * from './command' 3 | export * from './component' 4 | export * from './hook' 5 | export * from './inspector' 6 | export * from './plugin' 7 | export * from './router' 8 | export * from './tab' 9 | export * from './timeline' 10 | -------------------------------------------------------------------------------- /packages/devtools-kit/src/types/router.ts: -------------------------------------------------------------------------------- 1 | import type { RouteLocationNormalizedLoaded, RouteRecordNormalized } from 'vue-router' 2 | 3 | export type { Router } from 'vue-router' 4 | export interface RouterInfo { 5 | currentRoute: RouteLocationNormalizedLoaded | null | Record 6 | routes: RouteRecordNormalized[] 7 | // router: Router | null 8 | } 9 | -------------------------------------------------------------------------------- /packages/devtools-kit/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/index.ts', 6 | ], 7 | noExternal: ['speakingurl', 'superjson'], 8 | clean: true, 9 | format: ['esm', 'cjs'], 10 | dts: true, 11 | shims: true, 12 | }) 13 | -------------------------------------------------------------------------------- /packages/devtools-kit/types.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export * from './dist/index' 3 | -------------------------------------------------------------------------------- /packages/devtools/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools 2 | 3 | > This package provides a standalone vue-devtools application, that can be used to debug any Vue app regardless of the environment. Now you can debug your app opened in mobile browser, safari, native script etc. not just desktop chrome or firefox. 4 | 5 | ## Getting Started 6 | 7 | Please follow the documentation at [devtools.vuejs.org](https://devtools.vuejs.org/guide/standalone). 8 | -------------------------------------------------------------------------------- /packages/devtools/cli.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import('@vue/devtools-electron/cli') 3 | -------------------------------------------------------------------------------- /packages/devtools/hook.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/hook' 2 | -------------------------------------------------------------------------------- /packages/devtools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "author": "webfansplz", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/devtools", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "require": "./dist/index.cjs" 16 | }, 17 | "./hook": { 18 | "import": "./dist/hook.js", 19 | "require": "./dist/hook.cjs" 20 | } 21 | }, 22 | "main": "./dist/index.cjs", 23 | "module": "./dist/index.js", 24 | "bin": { 25 | "vue-devtools": "./cli.mjs" 26 | }, 27 | "files": [ 28 | "dist", 29 | "hook.d.ts" 30 | ], 31 | "scripts": { 32 | "build": "tsup --clean", 33 | "prepare:type": "tsup --dts-only", 34 | "stub": "tsup --watch --onSuccess 'tsup --dts-only'" 35 | }, 36 | "dependencies": { 37 | "@vue/devtools-electron": "workspace:^", 38 | "@vue/devtools-kit": "workspace:^" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/devtools/src/hook.ts: -------------------------------------------------------------------------------- 1 | import { devtools } from '@vue/devtools-kit' 2 | 3 | devtools.init() 4 | -------------------------------------------------------------------------------- /packages/devtools/src/index.ts: -------------------------------------------------------------------------------- 1 | import { connect } from '@vue/devtools-electron' 2 | import { devtools as _devtools, addCustomCommand, addCustomTab, onDevToolsClientConnected, onDevToolsConnected, removeCustomCommand } from '@vue/devtools-kit' 3 | 4 | export type * from '@vue/devtools-kit' 5 | 6 | const devtools = { 7 | ..._devtools, 8 | connect, 9 | } 10 | 11 | export { 12 | addCustomCommand, 13 | addCustomTab, 14 | devtools, 15 | onDevToolsClientConnected, 16 | onDevToolsConnected, 17 | removeCustomCommand, 18 | } 19 | -------------------------------------------------------------------------------- /packages/devtools/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/index.ts', 6 | 'src/hook.ts', 7 | ], 8 | external: [ 9 | 'vue', 10 | ], 11 | clean: true, 12 | format: ['esm', 'cjs'], 13 | dts: true, 14 | shims: true, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/electron/README.md: -------------------------------------------------------------------------------- 1 | # Electron 2 | 3 | > DevTools Electron App, used in [@vue/devtools](../devtools/README.md). 4 | -------------------------------------------------------------------------------- /packages/electron/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Vue DevTools 5 | 23 | 24 | 27 | 28 | 29 |
30 |
31 |

Loading DevTools Client...

32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /packages/electron/cli.d.ts: -------------------------------------------------------------------------------- 1 | export * from './dist/cli' 2 | -------------------------------------------------------------------------------- /packages/electron/icons/128-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/128-gray.png -------------------------------------------------------------------------------- /packages/electron/icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/128.png -------------------------------------------------------------------------------- /packages/electron/icons/16-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/16-gray.png -------------------------------------------------------------------------------- /packages/electron/icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/16.png -------------------------------------------------------------------------------- /packages/electron/icons/48-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/48-gray.png -------------------------------------------------------------------------------- /packages/electron/icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/electron/icons/48.png -------------------------------------------------------------------------------- /packages/electron/src/cli.ts: -------------------------------------------------------------------------------- 1 | import electron from 'electron' 2 | import { execaSync } from 'execa' 3 | import { resolve } from 'pathe' 4 | 5 | const appPath = decodeURIComponent(resolve(new URL('../dist/app.cjs', import.meta.url).pathname)) 6 | const argv = process.argv.slice(2) 7 | 8 | const result = execaSync(electron as unknown as string, [appPath].concat(argv), { 9 | stdio: 'inherit', 10 | windowsHide: false, 11 | }) 12 | 13 | process.exit(result.exitCode) 14 | -------------------------------------------------------------------------------- /packages/electron/src/index.ts: -------------------------------------------------------------------------------- 1 | import { target } from '@vue/devtools-shared' 2 | import { devtools } from '../../devtools-kit/src/index' 3 | 4 | export async function connect(host = 'http://localhost', port = 8098) { 5 | devtools.init() 6 | target.__VUE_DEVTOOLS_HOST__ = host 7 | target.__VUE_DEVTOOLS_PORT__ = port 8 | import('./user-app.js') 9 | } 10 | -------------------------------------------------------------------------------- /packages/electron/src/user-app.iife.ts: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client/dist/socket.io.js' 2 | import { init } from './user-app.core' 3 | 4 | init(io) 5 | -------------------------------------------------------------------------------- /packages/electron/src/user-app.ts: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client' 2 | import { init } from './user-app.core' 3 | 4 | init(io) 5 | -------------------------------------------------------------------------------- /packages/firefox-extension/README.md: -------------------------------------------------------------------------------- 1 | # Browser extension 2 | 3 | > DevTools Browser extension, still under development... 4 | -------------------------------------------------------------------------------- /packages/firefox-extension/devtools-background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/firefox-extension/devtools-panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /packages/firefox-extension/icons/128-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/128-beta.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/128-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/128-gray.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/128.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/128.nuxt.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/128.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/16-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/16-beta.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/16-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/16-gray.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/16.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/16.nuxt.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/16.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/48-beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/48-beta.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/48-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/48-gray.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/48.nuxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/48.nuxt.png -------------------------------------------------------------------------------- /packages/firefox-extension/icons/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/icons/48.png -------------------------------------------------------------------------------- /packages/firefox-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-firefox-extension", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "private": true, 6 | "author": "webfansplz", 7 | "license": "MIT", 8 | "files": [ 9 | "dist" 10 | ], 11 | "scripts": { 12 | "build": "cross-env NODE_ENV=production tsup", 13 | "dev": "cross-env NODE_ENV=development tsup --watch" 14 | }, 15 | "dependencies": { 16 | "@vue/devtools-core": "workspace:^", 17 | "@vue/devtools-kit": "workspace:^", 18 | "@vue/devtools-shared": "workspace:^" 19 | }, 20 | "devDependencies": { 21 | "@vitejs/plugin-vue": "catalog:", 22 | "vue": "catalog:" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/devtools-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/firefox-extension/popups/devtools-screenshot.png -------------------------------------------------------------------------------- /packages/firefox-extension/popups/disabled.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/disabled.nuxt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Nuxt + Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/disabled.vitepress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | VitePress + Vue.js is detected on this page.
6 | Devtools inspection is not available because it's in production mode or explicitly disabled by the author. 7 |

8 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/enabled.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/enabled.nuxt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | Nuxt + Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/enabled.vitepress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | Screenshot 7 |
8 | 9 |
10 |

11 | VitePress + Vue.js is detected on this page.
12 | Open DevTools and look for the Vue panel. 13 |

14 | 15 |

16 | Troubleshooting 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/not-found.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Vue.js not detected 6 |

7 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/popup.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700,700i'); 2 | 3 | body { 4 | font-family: Roboto, Avenir, Helvetica, Arial, sans-serif; 5 | font-size: 14px; 6 | font-weight: 400; 7 | line-height: 1.4; 8 | padding: 18px 24px; 9 | color: #2c3e50; 10 | } 11 | 12 | body, 13 | p { 14 | margin: 0; 15 | } 16 | 17 | p { 18 | min-width: 200px; 19 | max-width: 300px; 20 | } 21 | 22 | .short-paragraph { 23 | min-width: initial; 24 | white-space: nowrap; 25 | } 26 | 27 | a { 28 | color: #42b983; 29 | } 30 | 31 | .flex { 32 | display: flex; 33 | align-items: center; 34 | } 35 | 36 | .screenshot { 37 | position: relative; 38 | } 39 | 40 | .screenshot > img { 41 | width: 140px; 42 | height: 140px; 43 | object-fit: cover; 44 | border-radius: 100%; 45 | margin-right: 24px; 46 | box-shadow: 0 0 15px rgb(0 0 0 / 10%); 47 | } 48 | 49 | .migration-guide { 50 | width: 300px; 51 | margin: 0; 52 | padding: 0; 53 | } 54 | 55 | .migration-guide h2 { 56 | padding: 8px 0; 57 | margin: 0; 58 | } 59 | -------------------------------------------------------------------------------- /packages/firefox-extension/popups/vue2-migration-guide.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

Migration Tips

6 |

7 | Vue DevTools v7 detected in your Vue2 project. v7 only supports Vue3 and will not work. 8 |

9 |

10 | The legacy version that supports both Vue 2 and Vue 3 has been moved to 11 | here, please install and enable only the legacy version for your Vue2 app. If you're still using v5 version, you can 14 | install it 15 | here. 20 |

21 |
22 | -------------------------------------------------------------------------------- /packages/firefox-extension/src/devtools-overlay.ts: -------------------------------------------------------------------------------- 1 | const body = document.getElementsByTagName('body')[0] 2 | 3 | // create detector script 4 | const detector = document.createElement('script') 5 | detector.src = chrome.runtime.getURL('dist/detector.js') 6 | detector.onload = () => { 7 | detector.parentNode!.removeChild(detector) 8 | } 9 | 10 | ;(document.head || document.documentElement).appendChild(detector) 11 | 12 | window.addEventListener('message', (event) => { 13 | if (event.data.key === '__VUE_DEVTOOLS_VUE_DETECTED_EVENT__') { 14 | chrome.runtime.sendMessage(event.data.data) 15 | } 16 | }, false) 17 | -------------------------------------------------------------------------------- /packages/firefox-extension/src/injection.ts: -------------------------------------------------------------------------------- 1 | if (document instanceof HTMLDocument) { 2 | const content = chrome.runtime.getURL('dist/prepare.js') 3 | const script = document.createElement('script') 4 | script.src = content 5 | document.documentElement.appendChild(script) 6 | script.parentNode?.removeChild(script) 7 | } 8 | -------------------------------------------------------------------------------- /packages/firefox-extension/src/prepare.ts: -------------------------------------------------------------------------------- 1 | import { devtools } from '../../devtools-kit/src/index' 2 | 3 | devtools.init() 4 | 5 | window.__VUE_DEVTOOLS_BROWSER_EXTENSION_DETECTED__ = true 6 | -------------------------------------------------------------------------------- /packages/firefox-extension/src/proxy.ts: -------------------------------------------------------------------------------- 1 | // This is a content-script that is injected only when the devtools are 2 | // activated. Because it is not injected using eval, it has full privilege 3 | // to the chrome runtime API. It serves as a proxy between the injected 4 | // user application and the Vue devtools panel. 5 | 6 | import { createRpcProxy } from '@vue/devtools-kit' 7 | 8 | createRpcProxy({ 9 | preset: 'extension', 10 | }) 11 | -------------------------------------------------------------------------------- /packages/firefox-extension/src/user-app.ts: -------------------------------------------------------------------------------- 1 | import { functions } from '@vue/devtools-core' 2 | import { createRpcServer } from '@vue/devtools-kit' 3 | 4 | window.addEventListener('message', handshake) 5 | 6 | createRpcServer(functions, { 7 | preset: 'extension', 8 | }) 9 | 10 | function handshake(e: MessageEvent) { 11 | if (e.data.source === 'proxy->server' && e.data.payload.event === 'init') { 12 | window.removeEventListener('message', handshake) 13 | 14 | const listeners: ((event: unknown) => void)[] = [] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/firefox-extension/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig([{ 4 | entryPoints: [ 5 | 'src/*.ts', 6 | '!src/devtools-panel.ts', 7 | ], 8 | esbuildOptions(options) { 9 | if (options.format === 'iife') 10 | options.outExtension = { '.js': '.js' } 11 | }, 12 | define: { 13 | 'process.env': JSON.stringify(process.env), 14 | '__VUE_OPTIONS_API__': 'true', 15 | '__VUE_PROD_DEVTOOLS__': 'true', 16 | }, 17 | clean: true, 18 | format: ['iife'], 19 | minify: true, 20 | }, { 21 | entryPoints: [ 22 | 'src/devtools-panel.ts', 23 | ], 24 | define: { 25 | 'process.env': JSON.stringify(process.env), 26 | '__VUE_OPTIONS_API__': 'true', 27 | '__VUE_PROD_DEVTOOLS__': 'true', 28 | }, 29 | clean: true, 30 | format: ['esm'], 31 | minify: true, 32 | noExternal: ['@vue/devtools-core', '@vue/devtools-kit', '@vue/devtools-shared'], 33 | }]) 34 | -------------------------------------------------------------------------------- /packages/overlay/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Client 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/overlay/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-overlay", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "private": true, 6 | "author": "webfansplz", 7 | "license": "MIT", 8 | "exports": { 9 | "./*": "./dist/*" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "engines": { 15 | "node": ">=v14.21.3" 16 | }, 17 | "scripts": { 18 | "build": "vite build", 19 | "play": "vite --config vite.play.config.ts --open", 20 | "stub": "vite build --watch" 21 | }, 22 | "dependencies": { 23 | "@vue/devtools-core": "workspace:^", 24 | "@vue/devtools-kit": "workspace:*", 25 | "@vue/devtools-shared": "workspace:^", 26 | "@vue/devtools-ui": "workspace:*", 27 | "@vueuse/core": "catalog:" 28 | }, 29 | "devDependencies": { 30 | "@iconify/json": "catalog:", 31 | "@types/node": "catalog:", 32 | "@vitejs/plugin-vue": "catalog:", 33 | "sass-embedded": "catalog:", 34 | "vite": "catalog:", 35 | "vue": "catalog:" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/overlay/src/composables/iframe.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | 3 | export function useIframe(clientUrl: string, onLoad: () => void) { 4 | const iframe = ref() 5 | function getIframe() { 6 | if (iframe.value) 7 | return iframe.value 8 | iframe.value = document.createElement('iframe') 9 | iframe.value.id = 'vue-devtools-iframe' 10 | iframe.value.src = clientUrl 11 | iframe.value.setAttribute('data-v-inspector-ignore', 'true') 12 | iframe.value.onload = onLoad 13 | return iframe.value 14 | } 15 | 16 | return { 17 | getIframe, 18 | iframe, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/overlay/src/composables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './iframe' 2 | export * from './panel' 3 | export * from './position' 4 | export * from './state' 5 | -------------------------------------------------------------------------------- /packages/overlay/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | // ---- state ---- 2 | export const PANEL_PADDING = 10 3 | export const PANEL_MIN = 20 4 | export const PANEL_MAX = 100 5 | -------------------------------------------------------------------------------- /packages/overlay/src/main.ts: -------------------------------------------------------------------------------- 1 | import type { Component } from 'vue' 2 | import { createApp, h } from 'vue' 3 | 4 | import App from './App.vue' 5 | 6 | function createDevToolsContainer(App: Component) { 7 | const CONTAINER_ID = '__vue-devtools-container__' 8 | const el = document.createElement('div') 9 | el.setAttribute('id', CONTAINER_ID) 10 | el.setAttribute('data-v-inspector-ignore', 'true') 11 | document.getElementsByTagName('body')[0].appendChild(el) 12 | const app = createApp({ 13 | render: () => h(App), 14 | devtools: { 15 | hide: true, 16 | }, 17 | }) 18 | app.mount(el) 19 | } 20 | 21 | createDevToolsContainer(App) 22 | -------------------------------------------------------------------------------- /packages/overlay/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export function clamp(value: number, min: number, max: number) { 2 | return Math.min(Math.max(value, min), max) 3 | } 4 | 5 | export const checkIsSafari = () => navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome') 6 | 7 | export function pixelToNumber(value: string | number) { 8 | if (typeof value === 'string') 9 | return value.endsWith('px') ? +value.slice(0, -2) : +value 10 | return value 11 | } 12 | -------------------------------------------------------------------------------- /packages/overlay/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "lib": ["esnext", "dom"], 6 | "module": "esnext", 7 | "paths": { 8 | "~/*": ["./src/*"] 9 | } 10 | }, 11 | "include": ["**/*.ts", "**/*.d.ts", "**/*.vue"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/playground/applet/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Basic Playground 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/playground/applet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-applet", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite" 8 | }, 9 | "dependencies": { 10 | "@iconify/json": "catalog:", 11 | "@tresjs/core": "^4.3.3", 12 | "@vueuse/core": "catalog:", 13 | "pinia": "catalog:", 14 | "three": "^0.175.0", 15 | "unplugin-auto-import": "catalog:", 16 | "vue": "catalog:", 17 | "vue-router": "catalog:" 18 | }, 19 | "devDependencies": { 20 | "@types/three": "^0.175.0", 21 | "@vitejs/plugin-vue": "catalog:", 22 | "@vue/devtools-applet": "workspace:*", 23 | "@vue/devtools-core": "workspace:*", 24 | "@vue/devtools-kit": "workspace:*", 25 | "@vue/devtools-shared": "workspace:*", 26 | "sass-embedded": "catalog:", 27 | "serve": "catalog:", 28 | "typescript": "catalog:", 29 | "unocss": "catalog:", 30 | "vite": "catalog:", 31 | "vite-plugin-inspect": "catalog:", 32 | "vite-plugin-vue-devtools": "workspace:*" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/playground/applet/public/color-scheme.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches 3 | const setting = localStorage.getItem('color-schema') || 'auto' 4 | if (setting === 'dark' || (prefersDark && setting !== 'light')) 5 | document.documentElement.classList.toggle('dark', true) 6 | })() 7 | -------------------------------------------------------------------------------- /packages/playground/applet/src/components/Foo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/playground/applet/src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /packages/playground/applet/src/main.ts: -------------------------------------------------------------------------------- 1 | import Tres from '@tresjs/core' 2 | import { createPinia } from 'pinia' 3 | import App from './App.vue' 4 | import './style.css' 5 | import 'uno.css' 6 | import '@vue/devtools-applet/style.css' 7 | 8 | const pinia = createPinia() 9 | const app = createApp(App) 10 | app.use(pinia) 11 | 12 | app.use(Tres) 13 | app.mount('#app') 14 | -------------------------------------------------------------------------------- /packages/playground/applet/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | /* color-scheme: light dark; */ 8 | /* color: rgba(255, 255, 255, 0.87); */ 9 | /* background-color: #242424; */ 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | html { 19 | --at-apply: font-sans; 20 | overflow-y: scroll; 21 | overscroll-behavior: none; 22 | -ms-overflow-style: none; /* IE and Edge */ 23 | scrollbar-width: none; /* Firefox */ 24 | } 25 | 26 | html.dark { 27 | color-scheme: dark; 28 | } 29 | 30 | body { 31 | font-size: 16px; 32 | /* font-family: 'Roboto Mono, Menlo, Consolas, monospace'; */ 33 | } 34 | -------------------------------------------------------------------------------- /packages/playground/applet/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetIcons, 5 | presetTypography, 6 | presetUno, 7 | transformerDirectives, 8 | transformerVariantGroup, 9 | } from 'unocss' 10 | 11 | export default defineConfig({ 12 | presets: [ 13 | presetUno(), 14 | presetAttributify(), 15 | presetTypography(), 16 | presetIcons({ 17 | prefix: ['i-', ''], 18 | collections: {}, 19 | scale: 1.2, 20 | }), 21 | ], 22 | transformers: [ 23 | transformerDirectives(), 24 | transformerVariantGroup(), 25 | ], 26 | }) 27 | -------------------------------------------------------------------------------- /packages/playground/applet/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import Unocss from 'unocss/vite' 3 | 4 | import AutoImport from 'unplugin-auto-import/vite' 5 | import { defineConfig } from 'vite' 6 | import VueDevtools from 'vite-plugin-vue-devtools' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | plugins: [ 11 | vue(), 12 | VueDevtools(), 13 | Unocss(), 14 | AutoImport({ 15 | imports: [ 16 | 'vue', 17 | 'vue-router', 18 | '@vueuse/core', 19 | ], 20 | ignore: ['h'], 21 | }), 22 | ], 23 | css: { 24 | preprocessorOptions: { 25 | scss: { 26 | api: 'modern-compiler', 27 | }, 28 | }, 29 | }, 30 | server: { 31 | port: 3000, 32 | }, 33 | }) 34 | -------------------------------------------------------------------------------- /packages/playground/basic/assets/asset-in-root-assets.md: -------------------------------------------------------------------------------- 1 | # asset-in-root-assets 2 | -------------------------------------------------------------------------------- /packages/playground/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Basic Playground 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-basic", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite" 8 | }, 9 | "dependencies": { 10 | "@tanstack/vue-query": "^5.70.0", 11 | "@vueuse/core": "catalog:", 12 | "element-plus": "^2.9.7", 13 | "pinia": "catalog:", 14 | "unplugin-auto-import": "catalog:", 15 | "vee-validate": "^4.15.0", 16 | "vue": "catalog:", 17 | "vue-router": "catalog:", 18 | "vuex": "^4.1.0" 19 | }, 20 | "devDependencies": { 21 | "@rollup/plugin-commonjs": "^28.0.3", 22 | "@tanstack/vue-query-devtools": "^5.70.0", 23 | "@vitejs/plugin-vue": "catalog:", 24 | "@vue/devtools": "workspace:^", 25 | "sass-embedded": "catalog:", 26 | "serve": "catalog:", 27 | "typescript": "catalog:", 28 | "unocss": "catalog:", 29 | "vite": "catalog:", 30 | "vite-plugin-inspect": "catalog:", 31 | "vite-plugin-vue-devtools": "workspace:*" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/playground/basic/public/assets/asset-in-public-assets.md: -------------------------------------------------------------------------------- 1 | # asset-in-public-assets 2 | -------------------------------------------------------------------------------- /packages/playground/basic/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 38 | -------------------------------------------------------------------------------- /packages/playground/basic/src/components/DynamicApp.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /packages/playground/basic/src/components/Foo.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /packages/playground/basic/src/components/IndexComponent/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /packages/playground/basic/src/components/PropChild.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 18 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/CircularState.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 30 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/Hello.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 20 | 21 | 29 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/Hey.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 26 | 27 | 35 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/IntervalUpdate.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/PropMutation.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 27 | -------------------------------------------------------------------------------- /packages/playground/basic/src/pages/VeeValidate.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 34 | -------------------------------------------------------------------------------- /packages/playground/basic/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import { computed, ref } from 'vue' 3 | 4 | export const useAppStore = defineStore('app', () => { 5 | const count = ref(120) 6 | const map = ref(new Map([['a', 1], ['b', 2], ['c.test', 3]])) 7 | const set = ref(new Set([1, 2, 3])) 8 | const obj = ref({ 'foo.test': 1 }) 9 | function increment() { 10 | count.value++ 11 | } 12 | const doubledCount = computed(() => count.value * 2) 13 | 14 | return { count, doubledCount, increment, map, set, obj } 15 | }) 16 | 17 | export const useCounterStore = defineStore('counter', () => { 18 | const count = ref(10) 19 | const name = ref('webfansplz!!!') 20 | function increment() { 21 | count.value++ 22 | } 23 | 24 | return { count, name, increment } 25 | }) 26 | -------------------------------------------------------------------------------- /packages/playground/basic/src/stores/vuexStore.ts: -------------------------------------------------------------------------------- 1 | import { createStore } from 'vuex' 2 | 3 | export default createStore({ 4 | state: { 5 | counter: 0, 6 | }, 7 | mutations: { 8 | increment(state) { 9 | state.counter++ 10 | }, 11 | }, 12 | actions: { 13 | doubleIncrement({ commit }) { 14 | commit('increment') 15 | commit('increment') 16 | }, 17 | }, 18 | modules: { 19 | namespacedModule: { 20 | namespaced: true, 21 | state: () => ({ 22 | value: 'Hello, Vuex', 23 | }), 24 | getters: { 25 | exclamation(state) { 26 | return `${state.value}!!!!!!!` 27 | }, 28 | }, 29 | modules: { 30 | unnamespacedModule: { 31 | state: () => ({ 32 | value: 'unnamespacedModule', 33 | }), 34 | }, 35 | }, 36 | }, 37 | }, 38 | }) 39 | -------------------------------------------------------------------------------- /packages/playground/basic/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /packages/playground/basic/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetTypography, 5 | presetUno, 6 | transformerDirectives, 7 | transformerVariantGroup, 8 | } from 'unocss' 9 | 10 | export default defineConfig({ 11 | presets: [ 12 | presetUno(), 13 | presetAttributify(), 14 | presetTypography(), 15 | ], 16 | transformers: [ 17 | transformerDirectives(), 18 | transformerVariantGroup(), 19 | ], 20 | }) 21 | -------------------------------------------------------------------------------- /packages/playground/basic/vite.config.ts: -------------------------------------------------------------------------------- 1 | import commonjs from '@rollup/plugin-commonjs' 2 | import vue from '@vitejs/plugin-vue' 3 | import Unocss from 'unocss/vite' 4 | import AutoImport from 'unplugin-auto-import/vite' 5 | import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' 6 | import { defineConfig } from 'vite' 7 | import inspect from 'vite-plugin-inspect' 8 | import VueDevTools from 'vite-plugin-vue-devtools' 9 | // https://vitejs.dev/config/ 10 | export default defineConfig({ 11 | css: { 12 | preprocessorOptions: { 13 | scss: { 14 | api: 'modern-compiler', 15 | }, 16 | }, 17 | }, 18 | plugins: [ 19 | vue(), 20 | commonjs(), 21 | VueDevTools({ 22 | // launchEditor: 'code', 23 | }), 24 | Unocss(), 25 | AutoImport({ 26 | imports: [ 27 | 'vue', 28 | 'vue-router', 29 | '@vueuse/core', 30 | ], 31 | resolvers: [ElementPlusResolver()], 32 | }), 33 | inspect(), 34 | ], 35 | server: { 36 | port: 3000, 37 | }, 38 | }) 39 | -------------------------------------------------------------------------------- /packages/playground/multi-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Basic Playground 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/playground/multi-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-multi-app", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite" 8 | }, 9 | "dependencies": { 10 | "@vueuse/core": "catalog:", 11 | "pinia": "catalog:", 12 | "unplugin-auto-import": "catalog:", 13 | "vue": "catalog:", 14 | "vue-router": "catalog:" 15 | }, 16 | "devDependencies": { 17 | "@vitejs/plugin-vue": "catalog:", 18 | "sass-embedded": "catalog:", 19 | "serve": "catalog:", 20 | "typescript": "catalog:", 21 | "unocss": "catalog:", 22 | "vite": "catalog:", 23 | "vite-plugin-inspect": "catalog:", 24 | "vite-plugin-vue-devtools": "workspace:*" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/playground/multi-app/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /packages/playground/multi-app/src/App2.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /packages/playground/multi-app/src/components/Number.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /packages/playground/multi-app/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | 3 | import App2 from './App2.vue' 4 | import App from './App.vue' 5 | 6 | import './style.css' 7 | import 'uno.css' 8 | 9 | const app = createApp(App) 10 | 11 | const app2 = createApp(App2) 12 | 13 | app.mount('#app') 14 | 15 | app2.mount('#app2') 16 | -------------------------------------------------------------------------------- /packages/playground/multi-app/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /packages/playground/multi-app/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetTypography, 5 | presetUno, 6 | transformerDirectives, 7 | transformerVariantGroup, 8 | } from 'unocss' 9 | 10 | export default defineConfig({ 11 | presets: [ 12 | presetUno(), 13 | presetAttributify(), 14 | presetTypography(), 15 | ], 16 | transformers: [ 17 | transformerDirectives(), 18 | transformerVariantGroup(), 19 | ], 20 | }) 21 | -------------------------------------------------------------------------------- /packages/playground/multi-app/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import Unocss from 'unocss/vite' 3 | 4 | import AutoImport from 'unplugin-auto-import/vite' 5 | import { defineConfig } from 'vite' 6 | import VueDevtools from 'vite-plugin-vue-devtools' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | css: { 11 | preprocessorOptions: { 12 | scss: { 13 | api: 'modern-compiler', 14 | }, 15 | }, 16 | }, 17 | plugins: [ 18 | vue(), 19 | VueDevtools(), 20 | Unocss(), 21 | AutoImport({ 22 | imports: [ 23 | 'vue', 24 | 'vue-router', 25 | '@vueuse/core', 26 | ], 27 | }), 28 | ], 29 | server: { 30 | port: 3001, 31 | }, 32 | }) 33 | -------------------------------------------------------------------------------- /packages/playground/options-api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Basic Playground 8 | 9 | 14 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/playground/options-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-options-api", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite" 8 | }, 9 | "dependencies": { 10 | "vue": "catalog:" 11 | }, 12 | "devDependencies": { 13 | "@vitejs/plugin-vue": "catalog:", 14 | "vite-plugin-vue-devtools": "workspace:*" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/playground/options-api/src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /packages/playground/options-api/src/Options.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /packages/playground/options-api/src/Setup.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /packages/playground/options-api/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /packages/playground/options-api/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /packages/playground/options-api/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetTypography, 5 | presetUno, 6 | transformerDirectives, 7 | transformerVariantGroup, 8 | } from 'unocss' 9 | 10 | export default defineConfig({ 11 | presets: [ 12 | presetUno(), 13 | presetAttributify(), 14 | presetTypography(), 15 | ], 16 | transformers: [ 17 | transformerDirectives(), 18 | transformerVariantGroup(), 19 | ], 20 | }) 21 | -------------------------------------------------------------------------------- /packages/playground/options-api/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { defineConfig } from 'vite' 3 | import VueDevTools from 'vite-plugin-vue-devtools' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [ 8 | vue(), 9 | VueDevTools({ 10 | launchEditor: 'code', 11 | }), 12 | ], 13 | server: { 14 | port: 3000, 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue DevTools Plugin-SFC Playground 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-plugin-sfc", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "dev": "vite" 8 | }, 9 | "dependencies": { 10 | "vue": "catalog:" 11 | }, 12 | "devDependencies": { 13 | "@vitejs/plugin-vue": "catalog:", 14 | "@vue/devtools": "workspace:^", 15 | "typescript": "catalog:", 16 | "vite": "catalog:", 17 | "vite-plugin-inspect": "catalog:", 18 | "vite-plugin-vue-devtools": "workspace:*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/src/count.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/src/main.ts: -------------------------------------------------------------------------------- 1 | import { addCustomTab } from '@vue/devtools-kit' 2 | import { createApp } from 'vue' 3 | import App from './App.vue' 4 | import countSFC from './count.vue?raw' 5 | 6 | const app = createApp(App) 7 | app.mount('#app') 8 | 9 | setTimeout(() => { 10 | addCustomTab({ 11 | name: 'plugin_count', 12 | title: 'Plugin Count', 13 | icon: 'baseline-exposure-plus-1', 14 | view: { 15 | type: 'sfc', 16 | sfc: countSFC, 17 | }, 18 | category: 'app', 19 | }) 20 | }, 2000) 21 | -------------------------------------------------------------------------------- /packages/playground/plugin-sfc/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { defineConfig } from 'vite' 3 | import inspect from 'vite-plugin-inspect' 4 | import VueDevTools from 'vite-plugin-vue-devtools' 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [ 8 | vue(), 9 | VueDevTools(), 10 | inspect(), 11 | ], 12 | server: { 13 | port: 3000, 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /packages/playground/ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | UI Playground 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui-playground", 3 | "type": "module", 4 | "version": "7.3.2", 5 | "private": true, 6 | "scripts": { 7 | "build:ui-playground": "vue-tsc && vite build", 8 | "dev": "vite", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@unocss/reset": "catalog:", 13 | "@vue/devtools-ui": "workspace:*", 14 | "@vueuse/core": "catalog:", 15 | "vue": "catalog:" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-vue": "catalog:", 19 | "typescript": "catalog:", 20 | "unocss": "catalog:", 21 | "vite": "catalog:", 22 | "vue-tsc": "^2.2.8" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/playground/ui/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /packages/playground/ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import '@unocss/reset/tailwind.css' 4 | 5 | import 'uno.css' 6 | import './style.css' 7 | 8 | createApp(App).mount('#app') 9 | -------------------------------------------------------------------------------- /packages/playground/ui/src/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100vw; 3 | height: 100vh; 4 | } 5 | 6 | html.dark { 7 | background-color: #000; 8 | } 9 | -------------------------------------------------------------------------------- /packages/playground/ui/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/playground/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "jsx": "preserve", 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "useDefineForClassFields": true, 7 | "module": "ESNext", 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "allowImportingTsExtensions": true, 13 | 14 | /* Linting */ 15 | "strict": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noEmit": true, 20 | "isolatedModules": true, 21 | "skipLibCheck": true 22 | }, 23 | "references": [{ "path": "./tsconfig.node.json" }], 24 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] 25 | } 26 | -------------------------------------------------------------------------------- /packages/playground/ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "bundler", 6 | "allowSyntheticDefaultImports": true, 7 | "skipLibCheck": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/playground/ui/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { unoConfig } from '@vue/devtools-ui/theme' 2 | import { defineConfig, mergeConfigs } from 'unocss' 3 | 4 | export default defineConfig(mergeConfigs([unoConfig, { 5 | }])) 6 | -------------------------------------------------------------------------------- /packages/playground/ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import uno from 'unocss/vite' 3 | import { defineConfig } from 'vite' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue(), uno()], 8 | }) 9 | -------------------------------------------------------------------------------- /packages/playground/webpack/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset', 4 | ], 5 | } 6 | -------------------------------------------------------------------------------- /packages/playground/webpack/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/playground/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browserslist": [ 3 | "> 1%", 4 | "last 2 versions", 5 | "not dead", 6 | "not ie 11" 7 | ], 8 | "name": "webpack-playground", 9 | "version": "7.3.2", 10 | "private": true, 11 | "scripts": { 12 | "dev": "vue-cli-service serve" 13 | }, 14 | "dependencies": { 15 | "core-js": "^3.41.0", 16 | "vue": "catalog:" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.26.10", 20 | "@babel/eslint-parser": "^7.27.0", 21 | "@vue/cli-plugin-babel": "~5.0.8", 22 | "@vue/cli-plugin-eslint": "~5.0.8", 23 | "@vue/cli-service": "~5.0.8", 24 | "@vue/devtools": "workspace:*", 25 | "@vue/devtools-api": "workspace:*", 26 | "eslint": "^9.23.0", 27 | "eslint-plugin-vue": "^9.33.0" 28 | }, 29 | "eslintConfig": { 30 | "env": { 31 | "node": true 32 | }, 33 | "extends": [ 34 | "plugin:vue/vue3-essential", 35 | "eslint:recommended" 36 | ], 37 | "parserOptions": { 38 | "parser": "@babel/eslint-parser" 39 | }, 40 | "root": true, 41 | "rules": {} 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/playground/webpack/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/playground/webpack/public/favicon.ico -------------------------------------------------------------------------------- /packages/playground/webpack/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/playground/webpack/src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 16 | 17 | 27 | -------------------------------------------------------------------------------- /packages/playground/webpack/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuejs/devtools/01ee48167158178b7a07bed87ece379731267898/packages/playground/webpack/src/assets/logo.png -------------------------------------------------------------------------------- /packages/playground/webpack/src/main.js: -------------------------------------------------------------------------------- 1 | import { devtools } from '@vue/devtools' 2 | import { createApp } from 'vue' 3 | import App from './App.vue' 4 | 5 | devtools.connect('http://localhost', 8098) 6 | 7 | createApp(App).mount('#app') 8 | -------------------------------------------------------------------------------- /packages/playground/webpack/vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | 3 | module.exports = defineConfig({ 4 | transpileDependencies: false, 5 | devServer: { 6 | port: 3003, 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/shared/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools-shared 2 | 3 | > Internal utility types shared across @vue/devtools packages. 4 | -------------------------------------------------------------------------------- /packages/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/devtools-shared", 3 | "type": "module", 4 | "version": "7.7.6", 5 | "author": "webfansplz", 6 | "license": "MIT", 7 | "repository": { 8 | "directory": "packages/shared", 9 | "type": "git", 10 | "url": "git+https://github.com/vuejs/devtools.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "require": "./dist/index.cjs" 16 | } 17 | }, 18 | "main": "./dist/index.cjs", 19 | "module": "./dist/index.js", 20 | "files": [ 21 | "dist" 22 | ], 23 | "scripts": { 24 | "build": "tsup", 25 | "prepare:type": "tsup --dts-only", 26 | "stub": "tsup --watch --onSuccess 'tsup --dts-only'" 27 | }, 28 | "dependencies": { 29 | "rfdc": "^1.4.1" 30 | }, 31 | "devDependencies": { 32 | "@types/node": "catalog:" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/shared/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const VIEW_MODE_STORAGE_KEY = '__vue-devtools-view-mode__' 2 | export const VITE_PLUGIN_DETECTED_STORAGE_KEY = '__vue-devtools-vite-plugin-detected__' 3 | export const VITE_PLUGIN_CLIENT_URL_STORAGE_KEY = '__vue-devtools-vite-plugin-client-url__' 4 | export const BROADCAST_CHANNEL_NAME = '__vue-devtools-broadcast-channel__' 5 | -------------------------------------------------------------------------------- /packages/shared/src/env.ts: -------------------------------------------------------------------------------- 1 | export const isBrowser = typeof navigator !== 'undefined' 2 | export const target = (typeof window !== 'undefined' 3 | ? window 4 | : typeof globalThis !== 'undefined' 5 | ? globalThis 6 | // eslint-disable-next-line no-restricted-globals 7 | : typeof global !== 'undefined' 8 | // eslint-disable-next-line no-restricted-globals 9 | ? global 10 | : {}) as typeof globalThis 11 | 12 | export const isInChromePanel = typeof target.chrome !== 'undefined' && !!target.chrome.devtools 13 | export const isInIframe = isBrowser && target.self !== target.top 14 | export const isInElectron = typeof navigator !== 'undefined' && navigator.userAgent?.toLowerCase().includes('electron') 15 | // @ts-expect-error skip type check 16 | export const isNuxtApp = typeof window !== 'undefined' && !!window.__NUXT__ 17 | export const isInSeparateWindow = !isInIframe && !isInChromePanel && !isInElectron 18 | -------------------------------------------------------------------------------- /packages/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants' 2 | export * from './env' 3 | export * from './general' 4 | -------------------------------------------------------------------------------- /packages/shared/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/index.ts', 6 | ], 7 | clean: true, 8 | format: ['esm', 'cjs'], 9 | dts: true, 10 | shims: true, 11 | noExternal: ['rfdc'], 12 | }) 13 | -------------------------------------------------------------------------------- /packages/ui/README.md: -------------------------------------------------------------------------------- 1 | # @vue/devtools-ui 2 | 3 | > UI kit for DevTools. 4 | -------------------------------------------------------------------------------- /packages/ui/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/ui/src/components/Badge.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /packages/ui/src/components/Card.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/ui/src/components/DropdownButton.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | -------------------------------------------------------------------------------- /packages/ui/src/components/IcIcon.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /packages/ui/src/components/Icon.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /packages/ui/src/components/LoadingIndicator.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/ui/src/components/Overlay.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 28 | -------------------------------------------------------------------------------- /packages/ui/src/components/Tooltip.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 20 | -------------------------------------------------------------------------------- /packages/ui/src/composables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './notification' 2 | export type * from './notification' 3 | export * from './theme' 4 | -------------------------------------------------------------------------------- /packages/ui/src/composables/notification.ts: -------------------------------------------------------------------------------- 1 | import { h, render } from 'vue' 2 | import Notification from '../components/Notification.vue' 3 | 4 | // @unocss-include 5 | 6 | export type VueNotificationPlacement = 7 | | 'top-left' | 'top-center' | 'top-right' 8 | | 'bottom-left' | 'bottom-center' | 'bottom-right' 9 | 10 | export interface VueNotificationOptions { 11 | message: string 12 | type?: 'success' | 'error' | 'info' | 'warning' 13 | classes?: string 14 | duration?: number 15 | placement?: VueNotificationPlacement 16 | onClose?: () => void 17 | } 18 | 19 | export function showVueNotification(options: VueNotificationOptions) { 20 | const container = document.createElement('div') 21 | container.classList.add('$ui-z-max-override', 'fixed') 22 | document.body.appendChild(container) 23 | const originalOnClose = options.onClose 24 | function hide() { 25 | render(null, container) 26 | } 27 | 28 | options.onClose = () => { 29 | hide() 30 | originalOnClose?.() 31 | document.body.removeChild(container) 32 | } 33 | const vNode = h(Notification, options) 34 | render(vNode, container) 35 | } 36 | -------------------------------------------------------------------------------- /packages/ui/src/composables/theme.ts: -------------------------------------------------------------------------------- 1 | import type { UseColorModeOptions } from '@vueuse/core' 2 | import { useColorMode } from '@vueuse/core' 3 | import { computed } from 'vue' 4 | 5 | export const THEME_KEY = '__vue-devtools-theme__' 6 | 7 | export function useDevToolsColorMode(options: Omit = {}) { 8 | const colorMode = useColorMode({ 9 | ...options, 10 | storageKey: THEME_KEY, 11 | }) 12 | return { 13 | colorMode, 14 | isDark: computed(() => colorMode.value === 'dark'), 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/ui/src/index.ts: -------------------------------------------------------------------------------- 1 | // No need to import "uno.css" to generate a css bundle file 2 | // cause users will use UnoCSS to handle css fragment classes. 3 | import { vTooltip } from 'floating-vue' 4 | // Still provide a css bundle file for users who don't want to use UnoCSS. 5 | import '@unocss/reset/tailwind.css' 6 | 7 | import 'uno.css' 8 | import 'floating-vue/dist/style.css' 9 | 10 | export * from './components' 11 | export * from './composables' 12 | export * from './types' 13 | 14 | export { 15 | vTooltip, 16 | } 17 | -------------------------------------------------------------------------------- /packages/ui/src/types/floating-vue.ts: -------------------------------------------------------------------------------- 1 | import type { Placement } from 'floating-vue' 2 | 3 | export interface FloatingVueCommonProps { 4 | trigger?: 'click' | 'hover' 5 | distance?: number 6 | skidding?: number 7 | placement?: Placement 8 | disabled?: boolean 9 | shown?: boolean 10 | } 11 | -------------------------------------------------------------------------------- /packages/ui/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './floating-vue' 2 | -------------------------------------------------------------------------------- /packages/ui/storybook/Badge.story.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | -------------------------------------------------------------------------------- /packages/ui/storybook/Card.story.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | -------------------------------------------------------------------------------- /packages/ui/storybook/Checkbox.story.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | -------------------------------------------------------------------------------- /packages/ui/storybook/Confirm.story.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 35 | -------------------------------------------------------------------------------- /packages/ui/storybook/Dialog.story.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 32 | -------------------------------------------------------------------------------- /packages/ui/storybook/Drawer.story.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | -------------------------------------------------------------------------------- /packages/ui/storybook/IcIcon.story.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /packages/ui/storybook/Switch.story.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 25 | -------------------------------------------------------------------------------- /packages/ui/storybook/Tooltip.story.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 20 | -------------------------------------------------------------------------------- /packages/ui/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './theme' 2 | export * from './uno.config' 3 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "jsx": "preserve", 5 | "lib": ["esnext", "DOM"], 6 | "module": "esnext", 7 | "moduleResolution": "Bundler", 8 | "resolveJsonModule": true, 9 | "strict": true, 10 | "strictNullChecks": true, 11 | "esModuleInterop": true 12 | }, 13 | "include": [ 14 | "env.d.ts", 15 | "storybook/**/*.story.vue", 16 | "src/**/*", 17 | "src/**/*.vue" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /packages/ui/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'unocss' 2 | import { unoConfig } from './theme' 3 | 4 | export default defineConfig(unoConfig) 5 | -------------------------------------------------------------------------------- /packages/vite/README.md: -------------------------------------------------------------------------------- 1 | # vite-plugin-vue-devtools 2 | 3 | > `vite-plugin-vue-devtools` is a `Vite` plugin designed to enhance the `Vue` developer experience. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | 9 | npm add -D vite-plugin-vue-devtools 10 | 11 | ``` 12 | 13 | ## Usage 14 | 15 | ### Configuration Vite 16 | 17 | ```ts 18 | import { defineConfig } from 'vite' 19 | import VueDevTools from 'vite-plugin-vue-devtools' 20 | 21 | export default defineConfig({ 22 | plugins: [ 23 | VueDevTools(), 24 | vue(), 25 | ], 26 | }) 27 | ``` 28 | 29 | ## Documentation 30 | 31 | Check out all the DevTools details at [devtools.vuejs.org](https://devtools.vuejs.org). 32 | -------------------------------------------------------------------------------- /packages/vite/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | entries: [ 5 | 'src/vite', 6 | ], 7 | clean: true, 8 | declaration: true, 9 | externals: [ 10 | 'vite', 11 | 'vite-plugin-inspect', 12 | 'vite-plugin-vue-inspector', 13 | 'execa', 14 | ], 15 | rollup: { 16 | emitCJS: true, 17 | inlineDependencies: true, 18 | }, 19 | }) 20 | -------------------------------------------------------------------------------- /packages/vite/esbuild-shims/cjs-shim.ts: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'node:module' 2 | 3 | globalThis.require = createRequire(import.meta.url) 4 | -------------------------------------------------------------------------------- /packages/vite/src/dir.ts: -------------------------------------------------------------------------------- 1 | import { dirname, resolve } from 'node:path' 2 | import { fileURLToPath } from 'node:url' 3 | 4 | export const DIR_DIST = typeof __dirname !== 'undefined' 5 | ? __dirname 6 | : dirname(fileURLToPath(import.meta.url)) 7 | 8 | export const DIR_CLIENT = resolve(DIR_DIST, '../client') 9 | -------------------------------------------------------------------------------- /packages/vite/src/rpc/get-config.ts: -------------------------------------------------------------------------------- 1 | import { RpcFunctionCtx } from './types' 2 | 3 | export function getConfigFunctions(ctx: RpcFunctionCtx) { 4 | return { 5 | getRoot() { 6 | return ctx.config.root 7 | }, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/vite/src/rpc/graph.ts: -------------------------------------------------------------------------------- 1 | import type { ModuleInfo, ViteRPCFunctions } from '@vue/devtools-core' 2 | import { getViteRpcServer } from '@vue/devtools-kit' 3 | import { debounce } from 'perfect-debounce' 4 | import { RpcFunctionCtx } from './types' 5 | 6 | export function getGraphFunctions(ctx: RpcFunctionCtx) { 7 | const { rpc, server } = ctx 8 | const debouncedModuleUpdated = debounce(() => { 9 | getViteRpcServer?.()?.broadcast?.emit('graphModuleUpdated') 10 | }, 100) 11 | 12 | server.middlewares.use((_, __, next) => { 13 | debouncedModuleUpdated() 14 | next() 15 | }) 16 | return { 17 | async getGraphModules(): Promise { 18 | const list = await rpc.list() 19 | const modules = list?.modules || [] 20 | 21 | return modules 22 | }, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/vite/src/rpc/index.ts: -------------------------------------------------------------------------------- 1 | import { getAssetsFunctions } from './assets' 2 | import { getConfigFunctions } from './get-config' 3 | import { getGraphFunctions } from './graph' 4 | import { RpcFunctionCtx } from './types' 5 | 6 | export function getRpcFunctions(ctx: RpcFunctionCtx) { 7 | return { 8 | heartbeat() { 9 | return true 10 | }, 11 | ...getAssetsFunctions(ctx), 12 | ...getConfigFunctions(ctx), 13 | ...getGraphFunctions(ctx), 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/vite/src/rpc/types.ts: -------------------------------------------------------------------------------- 1 | import { ResolvedConfig, ViteDevServer } from 'vite' 2 | import { ViteInspectAPI } from 'vite-plugin-inspect/index' 3 | 4 | export interface RpcFunctionCtx { 5 | rpc: ViteInspectAPI['rpc'] 6 | server: ViteDevServer 7 | config: ResolvedConfig 8 | } 9 | -------------------------------------------------------------------------------- /packages/vite/src/utils.ts: -------------------------------------------------------------------------------- 1 | export function removeUrlQuery(url: string): string { 2 | return url.replace(/\?.*$/, '') 3 | } 4 | -------------------------------------------------------------------------------- /packages/vite/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | entryPoints: [ 5 | 'src/vite.ts', 6 | ], 7 | // To avoid esbuild compile import.meta.url to import_meta.url 8 | // See: https://github.com/vitejs/vite/issues/503 9 | target: 'es2020', 10 | clean: true, 11 | format: ['esm', 'cjs'], 12 | // Force esbuild to use .mjs extension for ESM output 13 | outExtension({ format }) { 14 | if (format === 'esm') { 15 | return { 16 | js: '.mjs', 17 | dts: '.d.ts', 18 | } 19 | } 20 | else if (format === 'cjs') { 21 | return { 22 | js: '.cjs', 23 | dts: '.d.cts', 24 | } 25 | } 26 | return { 27 | js: '.js', 28 | dts: '.d.ts', 29 | } 30 | }, 31 | // See: https://github.com/evanw/esbuild/issues/1921 32 | inject: ['./esbuild-shims/cjs-shim.ts'], 33 | dts: true, 34 | shims: true, 35 | }) 36 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/* 3 | - docs 4 | - packages/playground/** 5 | 6 | catalog: 7 | '@iconify/json': ^2.2.321 8 | '@types/node': ^22.13.14 9 | '@unocss/reset': ^66.0.0 10 | '@vitejs/plugin-vue': ^5.2.3 11 | '@vueuse/core': ^12.8.2 12 | '@vueuse/integrations': ^12.8.2 13 | colord: ^2.9.3 14 | execa: ^9.5.2 15 | floating-vue: 5.2.2 16 | mitt: ^3.0.1 17 | pathe: ^2.0.3 18 | perfect-debounce: ^1.0.0 19 | pinia: ^3.0.1 20 | sass-embedded: ^1.86.0 21 | serve: ^14.2.4 22 | shiki: ^3.2.1 23 | splitpanes: ^4.0.3 24 | typescript: ^5.8.2 25 | unocss: ^66.0.0 26 | unplugin-auto-import: ^19.1.2 27 | vite: ^6.2.1 28 | vite-hot-client: ^2.0.4 29 | vite-plugin-dts: ^4.5.3 30 | vite-plugin-inspect: 0.8.9 31 | vue: ^3.5.13 32 | vue-router: ^4.5.0 33 | vue-virtual-scroller: 2.0.0-beta.8 34 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'unocss' 2 | 3 | import config from './packages/client/uno.config' 4 | 5 | export default defineConfig({ 6 | ...config, 7 | configDeps: [ 8 | './packages/client/uno.config.ts', 9 | './packages/ui/uno.config.ts', 10 | ], 11 | }) 12 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import Vue from '@vitejs/plugin-vue' 2 | import AutoImport from 'unplugin-auto-import/vite' 3 | import { defineConfig } from 'vitest/config' 4 | 5 | export default defineConfig({ 6 | plugins: [Vue(), AutoImport({ 7 | imports: [ 8 | 'vue', 9 | 'vue-router', 10 | '@vueuse/core', 11 | ], 12 | dts: true, 13 | })], 14 | define: { 15 | __DEV__: true, 16 | __FEATURE_PROD_DEVTOOLS__: true, 17 | }, 18 | test: { 19 | globals: true, 20 | }, 21 | }) 22 | --------------------------------------------------------------------------------