@qwik.dev/devtools 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8030,171 +8030,199 @@ var import_src = __toESM(require_src(), 1);
8030
8030
  //#endregion
8031
8031
  //#region src/npm/index.ts
8032
8032
  const log$4 = (0, import_src.debug)("qwik:devtools:npm");
8033
- const packageCache = new Map();
8034
- const CACHE_TTL = 1e3 * 60 * 30;
8035
8033
  let preloadedDependencies = null;
8036
8034
  let isPreloading = false;
8037
8035
  let preloadPromise = null;
8038
- function getCachedPackage(name) {
8039
- const cached = packageCache.get(name);
8040
- if (cached && Date.now() - cached.timestamp < CACHE_TTL) return cached.data;
8041
- packageCache.delete(name);
8042
- return null;
8043
- }
8044
- function setCachedPackage(name, data) {
8045
- packageCache.set(name, {
8046
- data,
8047
- timestamp: Date.now()
8048
- });
8036
+ let dependenciesStatus = {
8037
+ phase: "idle",
8038
+ loaded: 0,
8039
+ total: 0,
8040
+ startedAt: null,
8041
+ finishedAt: null
8042
+ };
8043
+ async function fileExists(filePath) {
8044
+ try {
8045
+ await fsp.access(filePath);
8046
+ return true;
8047
+ } catch {
8048
+ return false;
8049
+ }
8049
8050
  }
8050
- async function findNearestFileUp(startDir, fileName) {
8051
+ async function readJsonFile(filePath) {
8051
8052
  try {
8052
- let currentDir = path.resolve(startDir);
8053
- for (let i = 0; i < 100; i++) {
8054
- const candidate = path.join(currentDir, fileName);
8055
- const exists = await fsp.access(candidate).then(() => true).catch(() => false);
8056
- if (exists) return candidate;
8057
- const parent = path.dirname(currentDir);
8058
- if (parent === currentDir) break;
8059
- currentDir = parent;
8060
- }
8061
- return null;
8053
+ const content = await fsp.readFile(filePath, "utf-8");
8054
+ return JSON.parse(content);
8062
8055
  } catch {
8063
8056
  return null;
8064
8057
  }
8065
8058
  }
8059
+ async function findNearestFileUp(startDir, fileName) {
8060
+ let currentDir = path.resolve(startDir);
8061
+ for (let i = 0; i < 100; i++) {
8062
+ const candidate = path.join(currentDir, fileName);
8063
+ if (await fileExists(candidate)) return candidate;
8064
+ const parent = path.dirname(currentDir);
8065
+ if (parent === currentDir) break;
8066
+ currentDir = parent;
8067
+ }
8068
+ return null;
8069
+ }
8066
8070
  function getProjectStartDirFromConfig(config) {
8067
8071
  if (config?.root) return config.root;
8068
8072
  if (config?.configFile) return path.dirname(config.configFile);
8069
8073
  return process.cwd();
8070
8074
  }
8071
- async function detectPackageManager(projectRoot) {
8072
- try {
8073
- if (await fsp.access(path.join(projectRoot, "pnpm-lock.yaml")).then(() => true).catch(() => false)) return "pnpm";
8074
- if (await fsp.access(path.join(projectRoot, "yarn.lock")).then(() => true).catch(() => false)) return "yarn";
8075
- if (await fsp.access(path.join(projectRoot, "package-lock.json")).then(() => true).catch(() => false)) return "npm";
8076
- return "pnpm";
8077
- } catch {
8078
- return "pnpm";
8079
- }
8075
+ function nodeModulesPackageJsonPath(projectRoot, name) {
8076
+ return path.join(projectRoot, "node_modules", ...name.split("/"), "package.json");
8077
+ }
8078
+ function normalizeRepositoryUrl(repository) {
8079
+ const url = typeof repository === "string" ? repository : repository?.url;
8080
+ if (!url || typeof url !== "string") return void 0;
8081
+ return url.replace(/^git\+/, "").replace(/^ssh:\/\/git@/, "https://").replace(/\.git$/, "");
8080
8082
  }
8081
- const preloadDependencies = async (config) => {
8082
- if (preloadedDependencies) {
8083
- log$4("[Qwik DevTools] Dependencies already preloaded");
8084
- return preloadedDependencies;
8083
+ function guessIconUrl(name, repositoryUrl) {
8084
+ if (name.startsWith("@")) {
8085
+ const scope = name.split("/")[0].substring(1);
8086
+ return `https://avatars.githubusercontent.com/${scope}?size=64`;
8085
8087
  }
8086
- if (isPreloading && preloadPromise) {
8087
- log$4("[Qwik DevTools] Preloading already in progress...");
8088
- return preloadPromise;
8088
+ if (repositoryUrl?.includes("github.com")) {
8089
+ const match$1 = repositoryUrl.match(/github\.com\/([^\/]+)/);
8090
+ if (match$1) return `https://avatars.githubusercontent.com/${match$1[1]}?size=64`;
8089
8091
  }
8092
+ return null;
8093
+ }
8094
+ function deferToEventLoop() {
8095
+ return new Promise((resolve$2) => setImmediate(resolve$2));
8096
+ }
8097
+ async function mapLimit(items, concurrency, fn) {
8098
+ if (items.length === 0) return [];
8099
+ const results = new Array(items.length);
8100
+ let cursor = 0;
8101
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
8102
+ while (true) {
8103
+ const i = cursor++;
8104
+ if (i >= items.length) return;
8105
+ results[i] = await fn(items[i], i);
8106
+ }
8107
+ });
8108
+ await Promise.all(workers);
8109
+ return results;
8110
+ }
8111
+ async function detectPackageManager(projectRoot) {
8112
+ if (await fileExists(path.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
8113
+ if (await fileExists(path.join(projectRoot, "yarn.lock"))) return "yarn";
8114
+ if (await fileExists(path.join(projectRoot, "package-lock.json"))) return "npm";
8115
+ return "pnpm";
8116
+ }
8117
+ async function phase1LocalIndex(projectRoot, deps) {
8118
+ const localConcurrency = 16;
8119
+ return mapLimit(deps, localConcurrency, async ([name, requestedVersion]) => {
8120
+ const pkgJsonPath = nodeModulesPackageJsonPath(projectRoot, name);
8121
+ const installedPkg = await readJsonFile(pkgJsonPath);
8122
+ const version = installedPkg?.version || requestedVersion;
8123
+ const repository = normalizeRepositoryUrl(installedPkg?.repository);
8124
+ const iconUrl = guessIconUrl(name, repository);
8125
+ const info = {
8126
+ name,
8127
+ version,
8128
+ description: installedPkg?.description || "No description available",
8129
+ author: installedPkg?.author,
8130
+ homepage: installedPkg?.homepage,
8131
+ repository,
8132
+ npmUrl: `https://www.npmjs.com/package/${name}`,
8133
+ iconUrl
8134
+ };
8135
+ dependenciesStatus.loaded++;
8136
+ if (dependenciesStatus.loaded % 50 === 0) await deferToEventLoop();
8137
+ return info;
8138
+ });
8139
+ }
8140
+ async function phase2BackgroundEnrich(deps) {
8141
+ const targets = deps.filter((p$1) => !p$1.repository || !p$1.iconUrl || p$1.description === "No description available");
8142
+ const enrichConcurrency = 6;
8143
+ await mapLimit(targets, enrichConcurrency, async (p$1) => {
8144
+ const repo = normalizeRepositoryUrl(p$1.repository);
8145
+ if (repo && repo !== p$1.repository) p$1.repository = repo;
8146
+ if (!p$1.iconUrl) p$1.iconUrl = guessIconUrl(p$1.name, p$1.repository);
8147
+ if (!p$1.repository || p$1.description === "No description available") try {
8148
+ const controller = new AbortController();
8149
+ const timeoutId = setTimeout(() => controller.abort(), 1500);
8150
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(p$1.name)}/${encodeURIComponent(p$1.version)}`, {
8151
+ headers: { Accept: "application/json" },
8152
+ signal: controller.signal
8153
+ });
8154
+ clearTimeout(timeoutId);
8155
+ if (res.ok) {
8156
+ const data = await res.json();
8157
+ if (!p$1.repository) p$1.repository = normalizeRepositoryUrl(data?.repository);
8158
+ if (p$1.description === "No description available" && data?.description) p$1.description = data.description;
8159
+ if (!p$1.iconUrl) p$1.iconUrl = guessIconUrl(p$1.name, p$1.repository);
8160
+ }
8161
+ } catch {}
8162
+ await deferToEventLoop();
8163
+ return p$1;
8164
+ });
8165
+ }
8166
+ async function preloadDependencies(config) {
8167
+ if (preloadedDependencies) return preloadedDependencies;
8168
+ if (isPreloading && preloadPromise) return preloadPromise;
8090
8169
  isPreloading = true;
8091
- log$4("[Qwik DevTools] Starting to preload dependencies...");
8170
+ dependenciesStatus = {
8171
+ phase: "phase1",
8172
+ loaded: 0,
8173
+ total: 0,
8174
+ startedAt: Date.now(),
8175
+ finishedAt: null
8176
+ };
8092
8177
  preloadPromise = (async () => {
8093
8178
  const startDir = getProjectStartDirFromConfig(config);
8094
- const pathToPackageJson = await findNearestFileUp(startDir, "package.json");
8095
- if (!pathToPackageJson) {
8179
+ const packageJsonPath = await findNearestFileUp(startDir, "package.json");
8180
+ if (!packageJsonPath) {
8096
8181
  preloadedDependencies = [];
8182
+ dependenciesStatus.phase = "done";
8183
+ dependenciesStatus.finishedAt = Date.now();
8097
8184
  isPreloading = false;
8098
- log$4("[Qwik DevTools] No package.json found");
8099
8185
  return [];
8100
8186
  }
8187
+ const projectRoot = path.dirname(packageJsonPath);
8188
+ const pkg = await readJsonFile(packageJsonPath);
8189
+ const allDeps = {
8190
+ ...pkg?.dependencies || {},
8191
+ ...pkg?.devDependencies || {},
8192
+ ...pkg?.peerDependencies || {}
8193
+ };
8194
+ const entries = Object.entries(allDeps);
8195
+ dependenciesStatus.total = entries.length;
8101
8196
  try {
8102
- const pkgJson = await fsp.readFile(pathToPackageJson, "utf-8");
8103
- const pkg = JSON.parse(pkgJson);
8104
- const allDeps = {
8105
- ...pkg.dependencies || {},
8106
- ...pkg.devDependencies || {},
8107
- ...pkg.peerDependencies || {}
8108
- };
8109
- const dependencies = Object.entries(allDeps);
8110
- const cachedPackages = [];
8111
- const uncachedDependencies = [];
8112
- for (const [name, version] of dependencies) {
8113
- const cached = getCachedPackage(name);
8114
- if (cached) cachedPackages.push({
8115
- ...cached,
8116
- version
8117
- });
8118
- else uncachedDependencies.push([name, version]);
8119
- }
8120
- if (uncachedDependencies.length === 0) {
8121
- preloadedDependencies = cachedPackages;
8122
- isPreloading = false;
8123
- return cachedPackages;
8124
- }
8125
- const batchSize = 100;
8126
- const batches = [];
8127
- for (let i = 0; i < uncachedDependencies.length; i += batchSize) batches.push(uncachedDependencies.slice(i, i + batchSize));
8128
- const fetchedPackages = [];
8129
- log$4(`[Qwik DevTools] Fetching ${uncachedDependencies.length} packages in parallel...`);
8130
- const allBatchPromises = batches.map(async (batch) => {
8131
- const batchPromises = batch.map(async ([name, version]) => {
8132
- try {
8133
- const controller = new AbortController();
8134
- const timeoutId = setTimeout(() => controller.abort(), 5e3);
8135
- const response = await fetch(`https://registry.npmjs.org/${name}`, {
8136
- headers: { "Accept": "application/json" },
8137
- signal: controller.signal
8138
- });
8139
- clearTimeout(timeoutId);
8140
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
8141
- const packageData = await response.json();
8142
- const latestVersion = packageData["dist-tags"]?.latest || version;
8143
- const versionData = packageData.versions?.[latestVersion] || packageData.versions?.[version];
8144
- let repositoryUrl = versionData?.repository?.url || packageData.repository?.url;
8145
- if (repositoryUrl) repositoryUrl = repositoryUrl.replace(/^git\+/, "").replace(/^ssh:\/\/git@/, "https://").replace(/\.git$/, "");
8146
- let iconUrl = null;
8147
- if (packageData.logo) iconUrl = packageData.logo;
8148
- else if (name.startsWith("@")) {
8149
- const scope = name.split("/")[0].substring(1);
8150
- iconUrl = `https://avatars.githubusercontent.com/${scope}?size=64`;
8151
- } else if (repositoryUrl?.includes("github.com")) {
8152
- const repoMatch = repositoryUrl.match(/github\.com\/([^\/]+)/);
8153
- if (repoMatch) iconUrl = `https://avatars.githubusercontent.com/${repoMatch[1]}?size=64`;
8154
- }
8155
- const packageInfo = {
8156
- name,
8157
- version,
8158
- description: versionData?.description || packageData.description || "No description available",
8159
- author: versionData?.author || packageData.author,
8160
- homepage: versionData?.homepage || packageData.homepage,
8161
- repository: repositoryUrl,
8162
- npmUrl: `https://www.npmjs.com/package/${name}`,
8163
- iconUrl
8164
- };
8165
- setCachedPackage(name, packageInfo);
8166
- return packageInfo;
8167
- } catch (error) {
8168
- const basicInfo = {
8169
- name,
8170
- version,
8171
- description: "No description available",
8172
- npmUrl: `https://www.npmjs.com/package/${name}`,
8173
- iconUrl: null
8174
- };
8175
- setCachedPackage(name, basicInfo);
8176
- return basicInfo;
8177
- }
8178
- });
8179
- const batchResults = await Promise.allSettled(batchPromises);
8180
- return batchResults.filter((result) => result.status === "fulfilled").map((result) => result.value);
8181
- });
8182
- const allBatchResults = await Promise.all(allBatchPromises);
8183
- for (const batchResult of allBatchResults) fetchedPackages.push(...batchResult);
8184
- const allPackages = [...cachedPackages, ...fetchedPackages];
8185
- preloadedDependencies = allPackages;
8186
- isPreloading = false;
8187
- log$4(`[Qwik DevTools] ✓ Successfully preloaded ${allPackages.length} dependencies`);
8188
- return allPackages;
8189
- } catch (error) {
8190
- log$4("[Qwik DevTools] ✗ Failed to preload dependencies:", error);
8197
+ const list = await phase1LocalIndex(projectRoot, entries);
8198
+ preloadedDependencies = list;
8199
+ dependenciesStatus.phase = "phase2";
8200
+ (async () => {
8201
+ try {
8202
+ await phase2BackgroundEnrich(list);
8203
+ dependenciesStatus.phase = "done";
8204
+ } catch (e) {
8205
+ dependenciesStatus.phase = "error";
8206
+ dependenciesStatus.error = e instanceof Error ? e.message : String(e);
8207
+ } finally {
8208
+ dependenciesStatus.finishedAt = Date.now();
8209
+ isPreloading = false;
8210
+ }
8211
+ })();
8212
+ log$4(`[Qwik DevTools] ✓ Phase1 preloaded ${list.length} dependencies (local-first)`);
8213
+ return list;
8214
+ } catch (e) {
8191
8215
  preloadedDependencies = [];
8216
+ dependenciesStatus.phase = "error";
8217
+ dependenciesStatus.error = e instanceof Error ? e.message : String(e);
8218
+ dependenciesStatus.finishedAt = Date.now();
8192
8219
  isPreloading = false;
8220
+ log$4("[Qwik DevTools] ✗ Failed to preload dependencies (local-first):", e);
8193
8221
  return [];
8194
8222
  }
8195
8223
  })();
8196
8224
  return preloadPromise;
8197
- };
8225
+ }
8198
8226
  async function startPreloading({ config }) {
8199
8227
  const startTime = Date.now();
8200
8228
  log$4("[Qwik DevTools] 🚀 Initiating dependency preload (background)...");
@@ -8213,8 +8241,7 @@ function getNpmFunctions({ config }) {
8213
8241
  const pathToPackageJson = await findNearestFileUp(startDir, "package.json");
8214
8242
  if (!pathToPackageJson) return [];
8215
8243
  try {
8216
- const pkgJson = await fsp.readFile(pathToPackageJson, "utf-8");
8217
- const pkg = JSON.parse(pkgJson);
8244
+ const pkg = await readJsonFile(pathToPackageJson);
8218
8245
  return Object.entries(pkg.devDependencies).filter(([key]) => /@qwik/i.test(key));
8219
8246
  } catch (error) {
8220
8247
  return [];
@@ -8225,12 +8252,26 @@ function getNpmFunctions({ config }) {
8225
8252
  log$4("[Qwik DevTools] Returning preloaded dependencies");
8226
8253
  return preloadedDependencies;
8227
8254
  }
8228
- if (isPreloading && preloadPromise) {
8229
- log$4("[Qwik DevTools] Waiting for preload to complete...");
8230
- return preloadPromise;
8231
- }
8255
+ if (isPreloading) return [];
8232
8256
  log$4("[Qwik DevTools] Warning: Preload not started, starting now...");
8233
- return preloadDependencies(config);
8257
+ preloadDependencies(config);
8258
+ return [];
8259
+ },
8260
+ async getDependenciesStatus() {
8261
+ return dependenciesStatus;
8262
+ },
8263
+ async refreshDependencies() {
8264
+ preloadedDependencies = null;
8265
+ isPreloading = false;
8266
+ preloadPromise = null;
8267
+ dependenciesStatus = {
8268
+ phase: "idle",
8269
+ loaded: 0,
8270
+ total: 0,
8271
+ startedAt: null,
8272
+ finishedAt: null
8273
+ };
8274
+ preloadDependencies(config);
8234
8275
  },
8235
8276
  async installPackage(packageName, isDev = true) {
8236
8277
  try {
@@ -9810,11 +9851,6 @@ const __qwik_perf_init_csr__ = () => {
9810
9851
  const __qwik_perf_get_ssr_store__ = () =>
9811
9852
  typeof process !== 'undefined' && process ? process : globalThis;
9812
9853
 
9813
- const __qwik_perf_to_error__ = (err) => ({
9814
- name: (err && err.name) || 'Error',
9815
- message: err && err.message ? String(err.message) : String(err),
9816
- });
9817
-
9818
9854
  const __qwik_perf_next_id__ = (perf) => {
9819
9855
  perf._id = (perf._id || 0) + 1;
9820
9856
  return perf._id;
@@ -9936,31 +9972,17 @@ function componentQrl(qrl, options) {
9936
9972
  if(qrl.dev){
9937
9973
  viteId = qrl.dev.file.replace(/[^/]*$/, qrl.dev.displayName);
9938
9974
  }
9939
- try {
9940
- const result = originalComponentQrl(qrl, options);
9941
- const duration = performance.now() - start;
9942
- __qwik_perf_commit_componentqrl__({
9943
- component,
9944
- phase,
9945
- duration,
9946
- start,
9947
- viteId,
9948
- end: start + duration,
9949
- });
9950
- return result;
9951
- } catch (err) {
9952
- const duration = performance.now() - start;
9953
- __qwik_perf_commit_componentqrl__({
9954
- component,
9955
- phase,
9956
- duration,
9957
- start,
9958
- viteId,
9959
- end: start + duration,
9960
- error: __qwik_perf_to_error__(err),
9961
- });
9962
- throw err;
9963
- }
9975
+ const result = originalComponentQrl(qrl, options);
9976
+ const duration = performance.now() - start;
9977
+ __qwik_perf_commit_componentqrl__({
9978
+ component,
9979
+ phase,
9980
+ duration,
9981
+ start,
9982
+ viteId,
9983
+ end: start + duration,
9984
+ });
9985
+ return result;
9964
9986
  }
9965
9987
 
9966
9988
  export { componentQrl };
@@ -10089,40 +10111,50 @@ const perfLazyWrapperPreamble = `${perfRuntime_default}
10089
10111
 
10090
10112
  // [qwik-component-proxy] Render function wrapper
10091
10113
  const __qwik_wrap__ = (fn, name, viteId) => {
10114
+ if (typeof fn !== 'function') return fn;
10092
10115
  let renderCount = 0;
10093
- return function (...args) {
10116
+
10117
+ function wrapped(...args) {
10094
10118
  renderCount += 1;
10095
10119
  const phase = __qwik_perf_is_server__() ? 'ssr' : 'csr';
10096
10120
  const start = performance.now();
10097
10121
 
10098
- try {
10099
- const result = fn.apply(this, args);
10100
- const duration = performance.now() - start;
10101
- __qwik_perf_commit__({
10102
- component: name,
10103
- phase,
10104
- duration,
10105
- start,
10106
- end: start + duration,
10107
- viteId,
10108
- renderCount,
10109
- });
10110
- return result;
10111
- } catch (err) {
10112
- const duration = performance.now() - start;
10113
- __qwik_perf_commit__({
10114
- component: name,
10115
- phase,
10116
- duration,
10117
- start,
10118
- end: start + duration,
10119
- error: __qwik_perf_to_error__(err),
10120
- viteId,
10121
- renderCount,
10122
- });
10123
- throw err;
10124
- }
10122
+ const result = fn.apply(this, args);
10123
+ const duration = performance.now() - start;
10124
+ __qwik_perf_commit__({
10125
+ component: name,
10126
+ phase,
10127
+ duration,
10128
+ start,
10129
+ end: start + duration,
10130
+ viteId,
10131
+ renderCount,
10132
+ });
10133
+ return result;
10134
+ }
10135
+
10136
+ // Preserve Qwik-compiler metadata attached to the original function.
10137
+ // (No try/catch per request; avoid touching special function props.)
10138
+ const skip = {
10139
+ length: true,
10140
+ name: true,
10141
+ arguments: true,
10142
+ caller: true,
10143
+ prototype: true,
10125
10144
  };
10145
+
10146
+ const descriptors = Object.getOwnPropertyDescriptors(fn);
10147
+ for (const key of Object.keys(descriptors)) {
10148
+ if (skip[key]) continue;
10149
+ Object.defineProperty(wrapped, key, descriptors[key]);
10150
+ }
10151
+
10152
+ for (const sym of Object.getOwnPropertySymbols(fn)) {
10153
+ const desc = Object.getOwnPropertyDescriptor(fn, sym);
10154
+ if (desc) Object.defineProperty(wrapped, sym, desc);
10155
+ }
10156
+
10157
+ return wrapped;
10126
10158
  };
10127
10159
  `;
10128
10160
  var perfLazyWrapperPreamble_default = perfLazyWrapperPreamble;
@@ -32,6 +32,21 @@ function getClientRpcFunctions() {
32
32
  healthCheck: () => true
33
33
  };
34
34
  }
35
+ function toDevtoolsRoutes(routes) {
36
+ const children = routes?.children || [];
37
+ const directories = children.filter((child) => child.type === re.DIRECTORY);
38
+ return [
39
+ {
40
+ relativePath: "",
41
+ name: "index",
42
+ type: re.DIRECTORY,
43
+ path: "",
44
+ isSymbolicLink: false,
45
+ children: void 0
46
+ },
47
+ ...directories
48
+ ];
49
+ }
35
50
  const QwikDevtools = component$(() => {
36
51
  useStyles$(globalCss);
37
52
  const state = useStore({
@@ -44,7 +59,6 @@ const QwikDevtools = component$(() => {
44
59
  allDependencies: [],
45
60
  isLoadingDependencies: false
46
61
  });
47
- const clientReady = useSignal(false);
48
62
  useVisibleTask$(async () => {
49
63
  const hot = await tryCreateHotContext(void 0, [
50
64
  "/"
@@ -54,78 +68,43 @@ const QwikDevtools = component$(() => {
54
68
  }
55
69
  setViteClientContext(hot);
56
70
  createClientRpc(getClientRpcFunctions());
57
- clientReady.value = true;
58
- });
59
- useVisibleTask$(async ({ track }) => {
60
- track(() => clientReady.value);
61
- if (!clientReady.value) return;
62
- const rpc = getViteClientRpc();
63
- try {
64
- const assets = await rpc.getAssetsFromPublicDir();
65
- state.assets = assets;
66
- } catch (error) {
67
- log("Failed to load assets:", error);
68
- }
69
- });
70
- useVisibleTask$(async ({ track }) => {
71
- track(() => clientReady.value);
72
- if (!clientReady.value) return;
73
- const rpc = getViteClientRpc();
74
- try {
75
- const components = await rpc.getComponents();
76
- state.components = components;
77
- } catch (error) {
78
- log("Failed to load components:", error);
79
- }
80
- });
81
- useVisibleTask$(async ({ track }) => {
82
- track(() => clientReady.value);
83
- if (!clientReady.value) return;
84
- const rpc = getViteClientRpc();
85
- try {
86
- const routes = await rpc.getRoutes();
87
- const children = routes?.children || [];
88
- const directories = children.filter((child) => child.type === "directory");
89
- const values = [
90
- {
91
- relativePath: "",
92
- name: "index",
93
- type: re.DIRECTORY,
94
- path: "",
95
- isSymbolicLink: false,
96
- children: void 0
97
- },
98
- ...directories
99
- ];
100
- state.routes = noSerialize(values);
101
- } catch (error) {
102
- log("Failed to load routes:", error);
103
- }
104
- });
105
- useVisibleTask$(async ({ track }) => {
106
- track(() => clientReady.value);
107
- if (!clientReady.value) return;
108
- const rpc = getViteClientRpc();
109
- try {
110
- const qwikPackages = await rpc.getQwikPackages();
111
- state.npmPackages = qwikPackages;
112
- } catch (error) {
113
- log("Failed to load Qwik packages:", error);
114
- }
115
- });
116
- useVisibleTask$(async ({ track }) => {
117
- track(() => clientReady.value);
118
- if (!clientReady.value) return;
119
71
  const rpc = getViteClientRpc();
72
+ const group1 = Promise.allSettled([
73
+ rpc.getAssetsFromPublicDir(),
74
+ rpc.getComponents(),
75
+ rpc.getRoutes(),
76
+ rpc.getQwikPackages()
77
+ ]);
120
78
  state.isLoadingDependencies = true;
121
- try {
122
- const allDeps = await rpc.getAllDependencies();
79
+ const depsPromise = rpc.getAllDependencies().then((allDeps) => {
123
80
  state.allDependencies = allDeps;
124
- } catch (error) {
81
+ }).catch((error) => {
125
82
  log("Failed to load all dependencies:", error);
126
- } finally {
83
+ }).finally(() => {
127
84
  state.isLoadingDependencies = false;
85
+ });
86
+ const [assetsRes, componentsRes, routesRes, packagesRes] = await group1;
87
+ if (assetsRes.status === "fulfilled") {
88
+ state.assets = assetsRes.value;
89
+ } else {
90
+ log("Failed to load assets:", assetsRes.reason);
91
+ }
92
+ if (componentsRes.status === "fulfilled") {
93
+ state.components = componentsRes.value;
94
+ } else {
95
+ log("Failed to load components:", componentsRes.reason);
96
+ }
97
+ if (routesRes.status === "fulfilled") {
98
+ state.routes = noSerialize(toDevtoolsRoutes(routesRes.value));
99
+ } else {
100
+ log("Failed to load routes:", routesRes.reason);
101
+ }
102
+ if (packagesRes.status === "fulfilled") {
103
+ state.npmPackages = packagesRes.value;
104
+ } else {
105
+ log("Failed to load Qwik packages:", packagesRes.reason);
128
106
  }
107
+ await depsPromise;
129
108
  });
130
109
  return /* @__PURE__ */ jsxs(Fragment, {
131
110
  children: [
@@ -12,6 +12,15 @@ export interface ServerFunctions {
12
12
  getRoutes: () => any;
13
13
  getQwikPackages: () => Promise<[string, string][]>;
14
14
  getAllDependencies: () => Promise<any[]>;
15
+ getDependenciesStatus: () => Promise<{
16
+ phase: 'idle' | 'phase1' | 'phase2' | 'done' | 'error';
17
+ loaded: number;
18
+ total: number;
19
+ startedAt: number | null;
20
+ finishedAt: number | null;
21
+ error?: string;
22
+ }>;
23
+ refreshDependencies: () => Promise<void>;
15
24
  installPackage: (packageName: string, isDev?: boolean) => Promise<{
16
25
  success: boolean;
17
26
  error?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qwik.dev/devtools",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "license": "MIT",
5
5
  "main": "./dist/plugin/index.mjs",
6
6
  "description": "Qwik devtools package",