diff --git a/.changeset/two-paths-remain.md b/.changeset/two-paths-remain.md new file mode 100644 index 00000000..c5bed817 --- /dev/null +++ b/.changeset/two-paths-remain.md @@ -0,0 +1,6 @@ +--- +'@tanstack/devtools-vite': patch +'@tanstack/devtools-event-bus': patch +--- + +Add devtools vite plugin for enhanced functionalities diff --git a/docs/installation.md b/docs/installation.md index 19dd0bc9..19ff5b44 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -11,6 +11,7 @@ Only install one of the following packages depending on your use case: ```sh npm install @tanstack/react-devtools +npm install -D @tanstack/devtools-vite ``` TanStack Devtools is compatible with React v16.8+ @@ -19,6 +20,7 @@ TanStack Devtools is compatible with React v16.8+ ```sh npm install @tanstack/solid-devtools +npm install -D @tanstack/devtools-vite ``` TanStack Devtools is compatible with Solid v1.9.5+ diff --git a/docs/quick-start.md b/docs/quick-start.md index 4fb50176..5ea7acd0 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -7,8 +7,8 @@ TanStack Devtools is a framework-agnostic devtool for managing and debugging *de To get up and running install the correct adapter for your framework: -- **React**: `npm install @tanstack/react-devtools` -- **Solid**: `npm install @tanstack/solid-devtools` +- **React**: `npm install @tanstack/react-devtools @tanstack/devtools-vite` +- **Solid**: `npm install @tanstack/solid-devtools @tanstack/devtools-vite` Then import the devtools into the root of your application: @@ -25,6 +25,19 @@ function App() { } ``` +And plug the vite plugin as the first plugin in your plugin array in `vite.config.ts`: + +```javascript +import { devtools } from '@tanstack/devtools-vite' + +export default { + plugins: [ + devtools(), + // ... rest of your plugins here + ], +} +``` + And you're done! If you want to add custom plugins, you can do so by using the `plugins` prop: ```javascript diff --git a/docs/vite-plugin.md b/docs/vite-plugin.md new file mode 100644 index 00000000..77b7bca6 --- /dev/null +++ b/docs/vite-plugin.md @@ -0,0 +1,94 @@ +--- +title: Vite Plugin +id: vite-plugin +--- + +The Vite Plugin for TanStack Devtools provides a seamless integration for using the devtools in your Vite-powered applications. With this plugin, you get complementary features on top of the +existing features built into the devtools like better console logs, server event bus, and enhanced debugging capabilities. + +## Installation + +To add the devtools vite plugin you need to install it as a development dependency: + +```sh +npm install -D @tanstack/devtools-vite +``` + +Then add it as the *FIRST* plugin in your Vite config: + +```javascript +import { devtools } from '@tanstack/devtools-vite' + +export default { + plugins: [ + devtools(), + // ... rest of your plugins here + ], +} +``` + +And you're done! + +## Configuration + +You can configure the devtools plugin by passing options to the `devtools` function: + +```javascript +import { devtools } from '@tanstack/devtools-vite' + +export default { + plugins: [ + devtools({ + // options here + }), + // ... rest of your plugins here + ], +} +``` + +- `eventBusConfig` - Configuration for the event bus that the devtools use to communicate with the client + +```ts +{ + eventBusConfig: { + // port to run the event bus on + port: 1234, + // console log debug logs or not + debug: false + }, +} +``` + +- `appDir` - The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined. + +```javascript +{ + appDir: './src', +} +``` + +- `editor` - The open in editor configuration which has two fields, `name` and `open`, +`name` is the name of your editor, and `open` is a function that opens the editor with the given file and line number. You can implement your version for your editor as follows: + +```ts +const open = (file: string, line: number) => { + // implement your editor opening logic here +} + +{ + editor: { + name: 'vscode', + open + } +} +``` + + +- `enhancedLogs` - Configuration for enhanced logging. Defaults to enabled. + +```ts +{ + enhancedLogs: { + enabled: true + } +} \ No newline at end of file diff --git a/examples/react/basic/package.json b/examples/react/basic/package.json index be61120c..b155882e 100644 --- a/examples/react/basic/package.json +++ b/examples/react/basic/package.json @@ -20,6 +20,7 @@ "zod": "^4.0.14" }, "devDependencies": { + "@tanstack/devtools-vite": "0.2.2", "@types/react": "^19.1.2", "@types/react-dom": "^19.1.2", "@vitejs/plugin-react": "^4.5.2", diff --git a/examples/react/basic/vite.config.ts b/examples/react/basic/vite.config.ts index 4e194366..ef0a7c9b 100644 --- a/examples/react/basic/vite.config.ts +++ b/examples/react/basic/vite.config.ts @@ -1,9 +1,10 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' - +import { devtools } from '@tanstack/devtools-vite' // https://vite.dev/config/ export default defineConfig({ plugins: [ + devtools(), react({ // babel: { // plugins: [['babel-plugin-react-compiler', { target: '19' }]], diff --git a/examples/react/start/package.json b/examples/react/start/package.json index 2d483628..a488fa2a 100644 --- a/examples/react/start/package.json +++ b/examples/react/start/package.json @@ -36,6 +36,7 @@ "zod": "^4.0.14" }, "devDependencies": { + "@tanstack/devtools-vite": "0.2.2", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.2.0", "@types/react": "^19.1.2", diff --git a/examples/react/start/src/components/devtools.tsx b/examples/react/start/src/components/devtools.tsx index ede38977..e2c9d75b 100644 --- a/examples/react/start/src/components/devtools.tsx +++ b/examples/react/start/src/components/devtools.tsx @@ -13,7 +13,8 @@ export default function DevtoolsExample() { { constructor() { super({ pluginId: 'query-devtools', - debug: true, + debug: false, }) } } diff --git a/examples/react/start/src/routes/__root.tsx b/examples/react/start/src/routes/__root.tsx index 2d577fcd..7d9b8705 100644 --- a/examples/react/start/src/routes/__root.tsx +++ b/examples/react/start/src/routes/__root.tsx @@ -29,6 +29,7 @@ export const Route = createRootRoute({ }) function RootDocument({ children }: { children: React.ReactNode }) { + console.log('hello in root document') return ( diff --git a/examples/react/start/src/server-setup.ts b/examples/react/start/src/server-setup.ts deleted file mode 100644 index d6937f91..00000000 --- a/examples/react/start/src/server-setup.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ServerEventBus } from '@tanstack/devtools-event-bus/server' - -const devtoolsServer = new ServerEventBus() - -devtoolsServer.start() - -export { devtoolsServer } diff --git a/examples/react/start/vite.config.ts b/examples/react/start/vite.config.ts index 8a70c308..7a4f2a2d 100644 --- a/examples/react/start/vite.config.ts +++ b/examples/react/start/vite.config.ts @@ -3,10 +3,19 @@ import { tanstackStart } from '@tanstack/react-start/plugin/vite' import viteReact from '@vitejs/plugin-react' import viteTsConfigPaths from 'vite-tsconfig-paths' import tailwindcss from '@tailwindcss/vite' +import { devtools } from '@tanstack/devtools-vite' //import { devtoolsServer } from './src/server-setup' const config = defineConfig({ plugins: [ + devtools({ + eventBusConfig: { + debug: false, + }, + enhancedLogs: { + enabled: true, + }, + }), // this is the plugin that enables path aliases viteTsConfigPaths({ projects: ['./tsconfig.json'], diff --git a/package.json b/package.json index 874fa56b..c4801f08 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "overrides": { "@tanstack/devtools": "workspace:*", "@tanstack/react-devtools": "workspace:*", - "@tanstack/solid-devtools": "workspace:*" + "@tanstack/solid-devtools": "workspace:*", + "@tanstack/devtools-vite": "workspace:*" } } diff --git a/packages/devtools-vite/CHANGELOG.md b/packages/devtools-vite/CHANGELOG.md new file mode 100644 index 00000000..8ba74338 --- /dev/null +++ b/packages/devtools-vite/CHANGELOG.md @@ -0,0 +1,25 @@ +# @tanstack/devtools-event-client + +## 0.2.2 + +### Patch Changes + +- exclude from production by default ([#45](https://github.com/TanStack/devtools/pull/45)) + +## 0.2.1 + +### Patch Changes + +- add queued events to event bus ([#18](https://github.com/TanStack/devtools/pull/18)) + +## 0.2.0 + +### Minor Changes + +- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11)) + + - @tanstack/devtools now comes with an integrated Event Bus on the Client. + - The Event Bus allows for seamless communication between different parts of your running application + without tight coupling. + - Exposed APIs for publishing and subscribing to events. + - Added config for the client event bus diff --git a/packages/devtools-vite/README.md b/packages/devtools-vite/README.md new file mode 100644 index 00000000..1f76fb37 --- /dev/null +++ b/packages/devtools-vite/README.md @@ -0,0 +1,20 @@ +# @tanstack/devtools-vite + +This package is still under active development and might have breaking changes in the future. Please use it with caution. + +## General Usage + +The `@tanstack/devtools-vite` package is designed to work with Vite projects. +Plug it into your plugins array: + +```ts +import { devtools } from '@tanstack/devtools-vite' + +export default { + plugins: [ + // Important to include it first! + devtools(), + ... //rest of the plugins + ], +} +``` diff --git a/packages/devtools-vite/eslint.config.js b/packages/devtools-vite/eslint.config.js new file mode 100644 index 00000000..e472c69e --- /dev/null +++ b/packages/devtools-vite/eslint.config.js @@ -0,0 +1,10 @@ +// @ts-check + +import rootConfig from '../../eslint.config.js' + +export default [ + ...rootConfig, + { + rules: {}, + }, +] diff --git a/packages/devtools-vite/package.json b/packages/devtools-vite/package.json new file mode 100644 index 00000000..c5bc7b21 --- /dev/null +++ b/packages/devtools-vite/package.json @@ -0,0 +1,57 @@ +{ + "name": "@tanstack/devtools-vite", + "version": "0.2.2", + "description": "TanStack Vite plugin used to enhance the core devtools with additional functionalities", + "author": "Tanner Linsley", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/TanStack/devtools.git", + "directory": "packages/devtools" + }, + "homepage": "https://tanstack.com/devtools", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "keywords": [ + "devtools" + ], + "type": "module", + "types": "dist/esm//index.d.ts", + "module": "dist/esm/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + } + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "engines": { + "node": ">=18" + }, + "files": [ + "dist/", + "src" + ], + "scripts": { + "clean": "premove ./build ./dist", + "lint:fix": "eslint ./src --fix", + "test:eslint": "eslint ./src", + "test:lib": "vitest", + "test:lib:dev": "pnpm test:lib --watch", + "test:types": "tsc", + "test:build": "publint --strict", + "build": "vite build" + }, + "peerDependencies": { + "vite": "^7.0.0" + }, + "dependencies": { + "@tanstack/devtools-event-bus": "workspace:*", + "chalk": "^5.6.0" + } +} diff --git a/packages/devtools-vite/src/editor.ts b/packages/devtools-vite/src/editor.ts new file mode 100644 index 00000000..3fa45b6f --- /dev/null +++ b/packages/devtools-vite/src/editor.ts @@ -0,0 +1,92 @@ +import { normalizePath } from 'vite' +import { checkPath } from './utils.js' + +type OpenSourceData = { + type: 'open-source' + data: { + /** The source file to open */ + source?: string + /** The react router route ID, usually discovered via the hook useMatches */ + routeID?: string + /** The line number in the source file */ + line?: number + /** The column number in the source file */ + column?: number + } +} + +export type EditorConfig = { + /** The name of the editor, used for debugging purposes */ + name: string + /** Callback to open a file in the editor */ + open: ( + path: string, + lineNumber: string | undefined, + columnNumber?: string, + ) => Promise +} + +export const DEFAULT_EDITOR_CONFIG: EditorConfig = { + name: 'VSCode', + open: async (path, lineNumber, columnNumber) => { + const { exec } = await import('node:child_process') + exec( + `code -g "${normalizePath(path).replaceAll('$', '\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}"`, + ) + }, +} + +export const handleOpenSource = async ({ + data, + openInEditor, + appDir, +}: { + data: OpenSourceData + appDir: string + openInEditor: EditorConfig['open'] +}) => { + const { source, line, routeID } = data.data + const lineNum = line ? `${line}` : undefined + const fs = await import('node:fs') + const path = await import('node:path') + if (source) { + return openInEditor(source, lineNum) + } + + if (routeID) { + const routePath = path.join(appDir, routeID) + const checkedPath = await checkPath(routePath) + + if (!checkedPath) return + const { type, validPath } = checkedPath + + const reactExtensions = ['tsx', 'jsx'] + const allExtensions = ['ts', 'js', ...reactExtensions] + const isRoot = routeID === 'root' + const findFileByExtension = (prefix: string, filePaths: Array) => { + const file = filePaths.find((file) => + allExtensions.some((ext) => file === `${prefix}.${ext}`), + ) + return file + } + + if (isRoot) { + if (!fs.existsSync(appDir)) return + const filesInReactRouterPath = fs.readdirSync(appDir) + const rootFile = findFileByExtension('root', filesInReactRouterPath) + rootFile && openInEditor(path.join(appDir, rootFile), lineNum) + return + } + + // If its not the root route, then we find the file or folder in the routes folder + // We know that the route ID is in the form of "routes/contact" or "routes/user.profile" when is not root + // so the ID already contains the "routes" segment, so we just need to find the file or folder in the routes folder + if (type === 'directory') { + const filesInFolderRoute = fs.readdirSync(validPath) + const routeFile = findFileByExtension('route', filesInFolderRoute) + routeFile && openInEditor(path.join(appDir, routeID, routeFile), lineNum) + return + } + return openInEditor(validPath, lineNum) + } +} diff --git a/packages/devtools-vite/src/index.ts b/packages/devtools-vite/src/index.ts new file mode 100644 index 00000000..06e031f4 --- /dev/null +++ b/packages/devtools-vite/src/index.ts @@ -0,0 +1,2 @@ +export { devtools, defineDevtoolsConfig } from './plugin' +export type { TanStackDevtoolsViteConfig } from './plugin' diff --git a/packages/devtools-vite/src/plugin.ts b/packages/devtools-vite/src/plugin.ts new file mode 100644 index 00000000..58a8945b --- /dev/null +++ b/packages/devtools-vite/src/plugin.ts @@ -0,0 +1,145 @@ +import { normalizePath } from 'vite' +import chalk from 'chalk' +import { ServerEventBus } from '@tanstack/devtools-event-bus/server' +import { handleDevToolsViteRequest } from './utils' +import { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor' +import type { EditorConfig } from './editor' +import type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server' +import type { Plugin } from 'vite' + +export type TanStackDevtoolsViteConfig = { + /** The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined. */ + appDir?: string + /** + * Configuration for the editor integration. Defaults to opening in VS code + */ + editor?: EditorConfig + /** + * The configuration options for the server event bus + */ + eventBusConfig?: ServerEventBusConfig + /** + * Configuration for enhanced logging. + */ + enhancedLogs?: { + /** + * Whether to enable enhanced logging. + * @default true + */ + enabled: boolean + } +} + +export const defineDevtoolsConfig = (config: TanStackDevtoolsViteConfig) => + config + +export const devtools = (args?: TanStackDevtoolsViteConfig): Array => { + let port = 5173 + const appDir = args?.appDir || './src' + const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true } + const bus = new ServerEventBus(args?.eventBusConfig) + + return [ + { + enforce: 'pre', + name: '@tanstack/devtools:custom-server', + apply(config) { + // Custom server is only needed in development for piping events to the client + return config.mode === 'development' + }, + configureServer(server) { + bus.start() + server.middlewares.use((req, _res, next) => { + if (req.socket.localPort && req.socket.localPort !== port) { + port = req.socket.localPort + } + next() + }) + if (server.config.server.port) { + port = server.config.server.port + } + + server.httpServer?.on('listening', () => { + port = server.config.server.port + }) + + const editor = args?.editor ?? DEFAULT_EDITOR_CONFIG + const openInEditor = async ( + path: string | undefined, + lineNum: string | undefined, + ) => { + if (!path) { + return + } + await editor.open(path, lineNum) + } + server.middlewares.use((req, res, next) => + handleDevToolsViteRequest(req, res, next, (parsedData) => { + const { data, routine } = parsedData + if (routine === 'open-source') { + return handleOpenSource({ + data: { type: data.type, data }, + openInEditor, + appDir, + }) + } + return + }), + ) + }, + }, + { + name: '@tanstack/devtools:better-console-logs', + enforce: 'pre', + apply(config) { + return config.mode === 'development' && enhancedLogsConfig.enabled + }, + transform(code, id) { + // Ignore anything external + if ( + id.includes('node_modules') || + id.includes('?raw') || + id.includes('dist') || + id.includes('build') + ) + return code + + if (!code.includes('console.')) { + return code + } + const lines = code.split('\n') + return lines + .map((line, lineNumber) => { + if ( + line.trim().startsWith('//') || + line.trim().startsWith('/**') || + line.trim().startsWith('*') + ) { + return line + } + // Do not add for arrow functions or return statements + if ( + line.replaceAll(' ', '').includes('=>console.') || + line.includes('return console.') + ) { + return line + } + + const column = line.indexOf('console.') + const location = `${id.replace(normalizePath(process.cwd()), '')}:${lineNumber + 1}:${column + 1}` + const logMessage = `'${chalk.magenta('LOG')} ${chalk.blueBright(`${location} - http://localhost:${port}/__tsd/open-source?source=${encodeURIComponent(id.replace(normalizePath(process.cwd()), ''))}&line=${lineNumber + 1}&column=${column + 1}`)}\\n → '` + if (line.includes('console.log(')) { + const newLine = `console.log(${logMessage},` + return line.replace('console.log(', newLine) + } + if (line.includes('console.error(')) { + const newLine = `console.error(${logMessage},` + return line.replace('console.error(', newLine) + } + return line + }) + .join('\n') + }, + }, + ] +} diff --git a/packages/devtools-vite/src/utils.ts b/packages/devtools-vite/src/utils.ts new file mode 100644 index 00000000..2f1e18bd --- /dev/null +++ b/packages/devtools-vite/src/utils.ts @@ -0,0 +1,70 @@ +import { normalizePath } from 'vite' +import type { Connect } from 'vite' +import type { IncomingMessage, ServerResponse } from 'node:http' + +export const handleDevToolsViteRequest = ( + req: Connect.IncomingMessage, + res: ServerResponse, + next: Connect.NextFunction, + cb: (data: any) => void, +) => { + if (req.url?.includes('__tsd/open-source')) { + const searchParams = new URLSearchParams(req.url.split('?')[1]) + const source = searchParams.get('source') + const line = searchParams.get('line') + const column = searchParams.get('column') + cb({ + type: 'open-source', + routine: 'open-source', + data: { + source: source + ? normalizePath(`${process.cwd()}/${source}`) + : undefined, + line, + column, + }, + }) + res.setHeader('Content-Type', 'text/html') + res.write(``) + res.end() + return + } + if (!req.url?.includes('__tsd')) { + return next() + } + + const chunks: Array = [] + req.on('data', (chunk) => { + chunks.push(chunk) + }) + req.on('end', () => { + const dataToParse = Buffer.concat(chunks) + try { + const parsedData = JSON.parse(dataToParse.toString()) + cb(parsedData) + } catch (e) {} + res.write('OK') + }) +} + +export async function checkPath( + routePath: string, + extensions = ['.tsx', '.jsx', '.ts', '.js'], +) { + const fs = await import('node:fs') + // Check if the path exists as a directory + if (fs.existsSync(routePath) && fs.lstatSync(routePath).isDirectory()) { + return { validPath: routePath, type: 'directory' } as const + } + + // Check if the path exists as a file with one of the given extensions + for (const ext of extensions) { + const filePath = `${routePath}${ext}` + if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) { + return { validPath: filePath, type: 'file' } as const + } + } + + // If neither a file nor a directory is found + return null +} diff --git a/packages/devtools-vite/tests/index.test.ts b/packages/devtools-vite/tests/index.test.ts new file mode 100644 index 00000000..2b66268c --- /dev/null +++ b/packages/devtools-vite/tests/index.test.ts @@ -0,0 +1,7 @@ +import { describe, it } from 'vitest' + +describe('test', () => { + it('works', () => { + // test implementation + }) +}) diff --git a/packages/devtools-vite/tests/test-setup.ts b/packages/devtools-vite/tests/test-setup.ts new file mode 100644 index 00000000..a9d0dd31 --- /dev/null +++ b/packages/devtools-vite/tests/test-setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/vitest' diff --git a/packages/devtools-vite/tsconfig.docs.json b/packages/devtools-vite/tsconfig.docs.json new file mode 100644 index 00000000..2880b4df --- /dev/null +++ b/packages/devtools-vite/tsconfig.docs.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["tests", "src"] +} diff --git a/packages/devtools-vite/tsconfig.json b/packages/devtools-vite/tsconfig.json new file mode 100644 index 00000000..44533f71 --- /dev/null +++ b/packages/devtools-vite/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] +} diff --git a/packages/devtools-vite/vite.config.ts b/packages/devtools-vite/vite.config.ts new file mode 100644 index 00000000..f7d6dca3 --- /dev/null +++ b/packages/devtools-vite/vite.config.ts @@ -0,0 +1,24 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackViteConfig } from '@tanstack/config/vite' +import packageJson from './package.json' + +const config = defineConfig({ + plugins: [], + test: { + name: packageJson.name, + dir: './', + watch: false, + environment: 'jsdom', + setupFiles: ['./tests/test-setup.ts'], + globals: true, + }, +}) + +export default mergeConfig( + config, + tanstackViteConfig({ + cjs: false, + entry: ['./src/index.ts'], + srcDir: './src', + }), +) diff --git a/packages/event-bus/src/server/index.ts b/packages/event-bus/src/server/index.ts index fce0ae18..015a9aa7 100644 --- a/packages/event-bus/src/server/index.ts +++ b/packages/event-bus/src/server/index.ts @@ -1,2 +1,2 @@ export { ServerEventBus } from './server' -export type { TanStackDevtoolsEvent } from './server' +export type { TanStackDevtoolsEvent, ServerEventBusConfig } from './server' diff --git a/packages/event-bus/src/server/server.ts b/packages/event-bus/src/server/server.ts index 93990e13..eada2ed2 100644 --- a/packages/event-bus/src/server/server.ts +++ b/packages/event-bus/src/server/server.ts @@ -20,6 +20,11 @@ declare global { var __EVENT_TARGET__: EventTarget | null } +export interface ServerEventBusConfig { + port?: number | undefined + debug?: boolean | undefined +} + export class ServerEventBus { #eventTarget: EventTarget #clients = new Set() @@ -36,7 +41,7 @@ export class ServerEventBus { #connectFunction = () => { this.#eventTarget.dispatchEvent(new CustomEvent('tanstack-connect-success')) } - constructor({ port = 42069, debug = false } = {}) { + constructor({ port = 42069, debug = false }: ServerEventBusConfig = {}) { this.#port = port this.#eventTarget = globalThis.__EVENT_TARGET__ ?? new EventTarget() // we want to set the global event target only once so that we can emit/listen to events on the server diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e504b22..ddf2641a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,6 +102,9 @@ importers: specifier: ^4.0.14 version: 4.0.14 devDependencies: + '@tanstack/devtools-vite': + specifier: 0.2.2 + version: link:../../../packages/devtools-vite '@types/react': specifier: ^19.1.2 version: 19.1.2 @@ -206,6 +209,9 @@ importers: specifier: ^4.0.14 version: 4.0.14 devDependencies: + '@tanstack/devtools-vite': + specifier: 0.2.2 + version: link:../../../packages/devtools-vite '@testing-library/dom': specifier: ^10.4.0 version: 10.4.1 @@ -237,6 +243,8 @@ importers: specifier: ^4.2.4 version: 4.2.4 + examples/react/start/generated/prisma: {} + examples/react/time-travel: dependencies: '@tanstack/devtools-event-client': @@ -367,6 +375,18 @@ importers: specifier: ^2.11.6 version: 2.11.6(@testing-library/jest-dom@6.6.3)(solid-js@1.9.7)(vite@7.0.6(@types/node@22.15.2)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + packages/devtools-vite: + dependencies: + '@tanstack/devtools-event-bus': + specifier: workspace:* + version: link:../event-bus + chalk: + specifier: ^5.6.0 + version: 5.6.0 + vite: + specifier: ^7.0.0 + version: 7.0.6(@types/node@22.15.2)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + packages/event-bus: dependencies: ws: @@ -3324,6 +3344,10 @@ packages: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.6.0: + resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -8010,7 +8034,7 @@ snapshots: '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -9635,7 +9659,7 @@ snapshots: '@typescript-eslint/types': 8.38.0 '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.0 + debug: 4.4.1 eslint: 9.25.1(jiti@2.5.1) typescript: 5.8.3 transitivePeerDependencies: @@ -9645,7 +9669,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) '@typescript-eslint/types': 8.38.0 - debug: 4.4.0 + debug: 4.4.1 typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -9680,7 +9704,7 @@ snapshots: '@typescript-eslint/types': 8.38.0 '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) '@typescript-eslint/utils': 8.38.0(eslint@9.25.1(jiti@2.5.1))(typescript@5.8.3) - debug: 4.4.0 + debug: 4.4.1 eslint: 9.25.1(jiti@2.5.1) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 @@ -9695,7 +9719,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.31.0 '@typescript-eslint/visitor-keys': 8.31.0 - debug: 4.4.0 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -9711,7 +9735,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) '@typescript-eslint/types': 8.38.0 '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.0 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -10369,6 +10393,8 @@ snapshots: chalk@5.4.1: {} + chalk@5.6.0: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {}