Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hungry-stingrays-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/devtools': patch
---

CHORE: add debug log and format
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Qwik devtools monorepo",
"scripts": {
"dev": "pnpm --filter plugin build && MODE=dev pnpm --parallel dev",
"playground": "MODE=dev pnpm --filter playground dev",
"playground": "MODE=dev DEBUG=qwik:devtools:* pnpm --filter playground dev",
"build": "tsx scripts/build-devtools.ts",
"change": "changeset",
"release": "changeset publish",
Expand All @@ -17,7 +17,9 @@
"@types/node": "^22.10.5",
"tsdown": "^0.9.6",
"tsx": "^4.19.2",
"vitest": "^3.2.4"
"vitest": "^3.2.4",
"debug": "4.4.3",
"@types/debug": "4.1.12"
},
"private": true,
"keywords": [
Expand Down
1 change: 0 additions & 1 deletion packages/playgrounds/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from '@qwik.dev/router';
import { RouterHead } from './components/router-head/router-head';
import './global.css';
import '../../devtools/dist/ui/style.css';
export default component$(() => {
/**
* The root of a QwikRouter site always start with the <QwikRouterProvider> component,
Expand Down
7 changes: 4 additions & 3 deletions packages/plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import useCollectHooksSource from './utils/useCollectHooks'
import { parseQwikCode } from './parse/parse';
import { startPreloading } from './npm/index';
import updateConf from './utils/updateConf';
import {debug} from 'debug'


const log = debug('qwik:devtools:plugin');
export function qwikDevtools(): Plugin[] {
let _config: ResolvedConfig;
const qwikData = new Map<string, any>();
Expand Down Expand Up @@ -47,7 +48,7 @@ export function qwikDevtools(): Plugin[] {
if (!preloadStarted) {
preloadStarted = true;
startPreloading({ config: _config }).catch((err) => {
console.error('[Qwik DevTools] Failed to start preloading:', err);
log('[Qwik DevTools] Failed to start preloading:', err);
});
}
},
Expand All @@ -62,7 +63,7 @@ export function qwikDevtools(): Plugin[] {
const importLine = `import { ${INNER_USE_HOOK} } from '${VIRTUAL_QWIK_DEVTOOLS_KEY}';\n`
code = importLine + code
}else {
console.log('importing virtual qwik devtools', VIRTUAL_QWIK_DEVTOOLS_KEY, code);
log('importing virtual qwik devtools', VIRTUAL_QWIK_DEVTOOLS_KEY, code);
}
code = parseQwikCode(code, {path: id})
}
Expand Down
7 changes: 5 additions & 2 deletions packages/plugin/src/inspect/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import fs from 'node:fs/promises'
import { parseQwikCode } from "../parse/parse";
import { ServerContext } from "../types";
import {debug} from 'debug'

const log = debug('qwik:devtools:inspect');
const codeStringCache = new Map<string, ReturnType<typeof parseQwikCode>>()

function parseCodeWithCache(code: string) {
Expand Down Expand Up @@ -41,7 +44,7 @@ export function getModulesContent(ctx: ServerContext) {
modules
};
} catch (error) {
console.log(`Failed to transform request for ${pathId}:`, error);
log(`Failed to transform request for ${pathId}:`, error);
return {
pathId,
modules: null,
Expand Down Expand Up @@ -98,7 +101,7 @@ export function getModulesContent(ctx: ServerContext) {

return []
} catch (error) {
console.error(`Failed to parse qwik code for ${pathId}:`, error);
log(`Failed to parse qwik code for ${pathId}:`, error);
return []
}

Expand Down
28 changes: 15 additions & 13 deletions packages/plugin/src/npm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import fsp from 'node:fs/promises';
import { NpmInfo } from '@devtools/kit';
import { execSync } from 'child_process';
import path from 'path';
import {debug} from 'debug'

const log = debug('qwik:devtools:npm');
// In-memory cache for npm package information
interface CacheEntry {
data: any;
Expand Down Expand Up @@ -100,17 +102,17 @@ export async function detectPackageManager(
// Preload dependencies function - moved to module scope
const preloadDependencies = async (config: any): Promise<any[]> => {
if (preloadedDependencies) {
console.log('[Qwik DevTools] Dependencies already preloaded');
log('[Qwik DevTools] Dependencies already preloaded');
return preloadedDependencies;
}

if (isPreloading && preloadPromise) {
console.log('[Qwik DevTools] Preloading already in progress...');
log('[Qwik DevTools] Preloading already in progress...');
return preloadPromise;
}

isPreloading = true;
console.log('[Qwik DevTools] Starting to preload dependencies...');
log('[Qwik DevTools] Starting to preload dependencies...');

preloadPromise = (async () => {
const startDir = getProjectStartDirFromConfig(config);
Expand All @@ -119,7 +121,7 @@ const preloadDependencies = async (config: any): Promise<any[]> => {
if (!pathToPackageJson) {
preloadedDependencies = [];
isPreloading = false;
console.log('[Qwik DevTools] No package.json found');
log('[Qwik DevTools] No package.json found');
return [];
}

Expand Down Expand Up @@ -163,7 +165,7 @@ const preloadDependencies = async (config: any): Promise<any[]> => {

const fetchedPackages: any[] = [];

console.log(`[Qwik DevTools] Fetching ${uncachedDependencies.length} packages in parallel...`);
log(`[Qwik DevTools] Fetching ${uncachedDependencies.length} packages in parallel...`);

const allBatchPromises = batches.map(async (batch) => {
const batchPromises = batch.map(async ([name, version]) => {
Expand Down Expand Up @@ -253,11 +255,11 @@ const preloadDependencies = async (config: any): Promise<any[]> => {
preloadedDependencies = allPackages;
isPreloading = false;

console.log(`[Qwik DevTools] ✓ Successfully preloaded ${allPackages.length} dependencies`);
log(`[Qwik DevTools] ✓ Successfully preloaded ${allPackages.length} dependencies`);

return allPackages;
} catch (error) {
console.error('[Qwik DevTools] ✗ Failed to preload dependencies:', error);
log('[Qwik DevTools] ✗ Failed to preload dependencies:', error);
preloadedDependencies = [];
isPreloading = false;
return [];
Expand All @@ -270,14 +272,14 @@ const preloadDependencies = async (config: any): Promise<any[]> => {
// Export function to start preloading from plugin initialization
export async function startPreloading({ config }: { config: any }) {
const startTime = Date.now();
console.log('[Qwik DevTools] 🚀 Initiating dependency preload (background)...');
log('[Qwik DevTools] 🚀 Initiating dependency preload (background)...');

// Start preloading in background, don't wait for it
preloadDependencies(config).then(() => {
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`[Qwik DevTools] ⚡ Preload completed in ${duration}s`);
log(`[Qwik DevTools] ⚡ Preload completed in ${duration}s`);
}).catch((err) => {
console.error('[Qwik DevTools] ✗ Preload failed:', err);
log('[Qwik DevTools] ✗ Preload failed:', err);
});

// Return immediately, don't block
Expand Down Expand Up @@ -305,18 +307,18 @@ export function getNpmFunctions({ config }: ServerContext) {
async getAllDependencies(): Promise<any[]> {
// Return preloaded data immediately if available
if (preloadedDependencies) {
console.log('[Qwik DevTools] Returning preloaded dependencies');
log('[Qwik DevTools] Returning preloaded dependencies');
return preloadedDependencies;
}

// If preloading is in progress, wait for it
if (isPreloading && preloadPromise) {
console.log('[Qwik DevTools] Waiting for preload to complete...');
log('[Qwik DevTools] Waiting for preload to complete...');
return preloadPromise;
}

// If preloading hasn't started (shouldn't happen), start it now
console.log('[Qwik DevTools] Warning: Preload not started, starting now...');
log('[Qwik DevTools] Warning: Preload not started, starting now...');
return preloadDependencies(config);
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const DevtoolsButton = component$(({ state }: DevtoolsButtonProps) => {
<div
ref={elementRef}
class={{
'fixed flex h-9 w-9 origin-center select-none items-center justify-center rounded-lg border border-border bg-background backdrop-blur-md':
'border-border bg-background fixed flex h-9 w-9 origin-center select-none items-center justify-center rounded-lg border backdrop-blur-md':
true,
'border-accent/50 bg-background/95 shadow-accent/35 rotate-90 shadow-lg':
state.isOpen.value && !isDragging.value,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/DevtoolsPanel/DevtoolsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const DevtoolsPanel = component$(({ state }: DevtoolsPanelProps) => {
return (
<div
ref={panelRef}
class="fixed bottom-6 right-6 flex h-[calc(100vh-3rem)] w-[calc(100vw-3rem)] translate-y-0 transform overflow-hidden rounded-lg border-2 border-border bg-background text-foreground backdrop-blur-lg transition-transform duration-300 ease-in-out"
class="border-border bg-background text-foreground fixed bottom-6 right-6 flex h-[calc(100vh-3rem)] w-[calc(100vw-3rem)] translate-y-0 transform overflow-hidden rounded-lg border-2 backdrop-blur-lg transition-transform duration-300 ease-in-out"
>
<Slot />
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Tab/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const Tab = component$<TabProps>(({ state, id, title }) => {
class={{
'flex h-10 w-10 items-center justify-center rounded-lg p-2.5 transition-all duration-200':
true,
'bg-transparent hover:bg-foreground/5 text-muted-foreground hover:text-foreground':
'hover:bg-foreground/5 text-muted-foreground hover:text-foreground bg-transparent':
state.activeTab !== id,
'shadow-accent/35 bg-accent text-white shadow-lg':
state.activeTab === id,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/TabContent/TabContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { component$, Slot } from '@qwik.dev/core';
export const TabContent = component$(() => {
return (
<div class="flex h-full w-full flex-col space-y-6">
<div class="flex items-center justify-between border-b border-border pb-4">
<div class="border-border flex items-center justify-between border-b pb-4">
<Slot name="title" />
</div>

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/ThemeToggle/QwikThemeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const QwikThemeToggle = component$(() => {
<>
<button
onClick$={onClick$}
class="group relative flex h-8 w-8 items-center justify-center rounded-md bg-background text-foreground hover:opacity-60"
class="bg-background text-foreground group relative flex h-8 w-8 items-center justify-center rounded-md hover:opacity-60"
>
<div class="absolute inset-0 grid place-items-center transition-transform duration-200 ease-out group-hover:scale-110 group-active:scale-75">
<HiSunOutline class="themeIcon light col-start-1 row-start-1" />
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const TreeNodeComponent = component$(
<div class={`inline-flex items-center rounded-md px-2 py-1`}>
{hasChildren ? (
<HiChevronUpMini
class={`mr-2 h-4 w-4 flex-shrink-0 text-muted-foreground transition-transform duration-200 ${
class={`text-muted-foreground mr-2 h-4 w-4 flex-shrink-0 transition-transform duration-200 ${
isExpanded.value ? 'rotate-90' : 'rotate-180'
}`}
/>
Expand Down
22 changes: 12 additions & 10 deletions packages/ui/src/devtools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
HiPhotoOutline,
HiMegaphoneMini,
HiCubeOutline,

HiCodeBracketSolid
HiCodeBracketSolid,
} from '@qwikest/icons/heroicons';
import { BsDiagram3 } from '@qwikest/icons/bootstrap';
import { LuFolderTree } from '@qwikest/icons/lucide';
Expand Down Expand Up @@ -41,6 +40,9 @@ import { Inspect } from './features/inspect/Inspect';
import { QwikThemeToggle } from './components/ThemeToggle/QwikThemeToggle';
import { ThemeScript as QwikThemeScript } from './components/ThemeToggle/theme-script';
import { CodeBreack } from './features/CodeBreack/CodeBreack';
import { debug } from 'debug';

const log = debug('qwik:devtools:devtools');
function getClientRpcFunctions() {
return {
healthCheck: () => true,
Expand Down Expand Up @@ -81,7 +83,7 @@ export const QwikDevtools = component$(() => {
const assets = await rpc.getAssetsFromPublicDir();
state.assets = assets;
} catch (error) {
console.error('Failed to load assets:', error);
log('Failed to load assets:', error);
}
});

Expand All @@ -93,7 +95,7 @@ export const QwikDevtools = component$(() => {
const components = await rpc.getComponents();
state.components = components;
} catch (error) {
console.error('Failed to load components:', error);
log('Failed to load components:', error);
}
});

Expand Down Expand Up @@ -122,7 +124,7 @@ export const QwikDevtools = component$(() => {

state.routes = noSerialize(values);
} catch (error) {
console.error('Failed to load routes:', error);
log('Failed to load routes:', error);
}
});

Expand All @@ -134,7 +136,7 @@ export const QwikDevtools = component$(() => {
const qwikPackages = await rpc.getQwikPackages();
state.npmPackages = qwikPackages;
} catch (error) {
console.error('Failed to load Qwik packages:', error);
log('Failed to load Qwik packages:', error);
}
});

Expand All @@ -147,7 +149,7 @@ export const QwikDevtools = component$(() => {
const allDeps = await rpc.getAllDependencies();
state.allDependencies = allDeps;
} catch (error) {
console.error('Failed to load all dependencies:', error);
log('Failed to load all dependencies:', error);
} finally {
state.isLoadingDependencies = false;
}
Expand All @@ -161,7 +163,7 @@ export const QwikDevtools = component$(() => {

{state.isOpen.value && (
<DevtoolsPanel state={state}>
<div class="bg-background/95 flex flex-col gap-2 border-r border-border p-3">
<div class="bg-background/95 border-border flex flex-col gap-2 border-r p-3">
<Tab state={state} id="overview" title="Overview">
<HiBoltOutline class="h-5 w-5" />
</Tab>
Expand All @@ -181,7 +183,7 @@ export const QwikDevtools = component$(() => {
<HiMegaphoneMini class="h-5 w-5" />
</Tab>
<Tab state={state} id="codeBreack" title="codeBreack">
< HiCodeBracketSolid class="h-5 w-5" />
<HiCodeBracketSolid class="h-5 w-5" />
</Tab>
<div class="mt-auto">
<QwikThemeToggle />
Expand All @@ -207,7 +209,7 @@ export const QwikDevtools = component$(() => {
{state.activeTab === 'assets' && (
<TabContent>
<TabTitle title="Public Assets" q:slot="title" />
<div class="flex gap-4 text-sm text-muted-foreground">
<div class="text-muted-foreground flex gap-4 text-sm">
<span>
Total Size:{' '}
{(
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/src/features/Assets/Assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const Assets = component$(({ state }: AssetsProps) => {
return (
<div
key={asset.filePath}
class="overflow-hidden rounded-xl border border-border bg-card-item-bg transition-all duration-200 hover:bg-card-item-hover-bg"
class="border-border bg-card-item-bg hover:bg-card-item-hover-bg overflow-hidden rounded-xl border transition-all duration-200"
>
{isImage ? (
<div class="aspect-square overflow-hidden bg-black/20">
Expand All @@ -29,7 +29,7 @@ export const Assets = component$(({ state }: AssetsProps) => {
</div>
) : (
<div class="flex aspect-square items-center justify-center bg-black/20">
<span class="font-mono text-2xl text-muted-foreground">
<span class="text-muted-foreground font-mono text-2xl">
{fileExt}
</span>
</div>
Expand All @@ -38,7 +38,7 @@ export const Assets = component$(({ state }: AssetsProps) => {
<div class="truncate text-sm" title={asset.path}>
{asset.path.split('/').pop()}
</div>
<div class="flex items-center justify-between text-xs text-muted-foreground">
<div class="text-muted-foreground flex items-center justify-between text-xs">
<span>{(asset.size / 1024).toFixed(2)} KB</span>
<span class="bg-foreground/5 rounded-full px-2 py-1">
{fileExt}
Expand Down
Loading
Loading