@antodevs/groundtruth 0.2.1 → 0.2.4

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.
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@antodevs/groundtruth",
3
- "version": "0.2.1",
3
+ "version": "0.2.4",
4
4
  "description": "Lightweight Node.js proxy to intercept API requests from coding agents and inject fresh web context",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
5
8
  "type": "module",
6
9
  "license": "MIT",
7
10
  "author": "Anto",
package/src/registry.js CHANGED
@@ -1,62 +1,55 @@
1
1
  /**
2
2
  * @module registry
3
- * @description Mappa hardcodata dipendenza URL docs ufficiale per bypass DDG su framework noti.
3
+ * @description Interroga il Cloudflare Worker (Remote Registry) per risolvere URL docs ufficiali.
4
4
  */
5
+ import fetch from 'node-fetch';
5
6
 
6
- // ─── Docs URL Registry ──────────────────────────────
7
-
8
- const DOCS_REGISTRY = {
9
- 'svelte': 'https://svelte.dev/docs/svelte/overview',
10
- 'sveltekit': 'https://svelte.dev/docs/kit/introduction',
11
- 'react': 'https://react.dev/reference/react',
12
- 'react-dom': 'https://react.dev/reference/react-dom',
13
- 'next': 'https://nextjs.org/docs',
14
- 'nextjs': 'https://nextjs.org/docs',
15
- 'vue': 'https://vuejs.org/api/',
16
- 'nuxt': 'https://nuxt.com/docs/api',
17
- 'angular': 'https://angular.dev/overview',
18
- 'astro': 'https://docs.astro.build/en/reference/configuration-reference/',
19
- 'tailwindcss': 'https://tailwindcss.com/docs',
20
- 'typescript': 'https://www.typescriptlang.org/docs/',
21
- 'express': 'https://expressjs.com/en/5x/api.html',
22
- 'fastify': 'https://fastify.dev/docs/latest/',
23
- 'hono': 'https://hono.dev/docs/',
24
- 'solid-js': 'https://docs.solidjs.com/',
25
- 'qwik': 'https://qwik.dev/docs/',
26
- 'remix': 'https://remix.run/docs/en/main',
27
- 'prisma': 'https://www.prisma.io/docs',
28
- 'drizzle-orm': 'https://orm.drizzle.team/docs/overview',
29
- 'three': 'https://threejs.org/docs/',
30
- 'zod': 'https://zod.dev/',
31
- 'trpc': 'https://trpc.io/docs',
32
- 'tanstack-query': 'https://tanstack.com/query/latest/docs/overview',
33
- };
7
+ const REGISTRY_API_URL = 'https://groundtruth-registry.antony-flex01.workers.dev/lookup';
8
+
9
+ // Cache in memoria per evitare query multiple allo stesso endpoint durante lo stesso run del watcher
10
+ const lookupCache = new Map();
34
11
 
35
12
  /**
36
- * @description Normalizza nome dipendenza e cerca URL docs nel registry.
13
+ * @description Interroga asincronamente l'API cloudflare per cercare URL docs nel registry remoto
37
14
  * @param {string} depName - Nome dipendenza da package.json (es. "svelte 5.51" o "@sveltejs/kit")
38
- * @returns {string|null} URL docs diretto o null se non trovato
15
+ * @returns {Promise<string|null>} URL docs diretto o null se non trovato/errore (fallback DDG cerniera)
39
16
  */
40
- export function lookupRegistryUrl(depName) {
41
- // Prende solo il nome senza versione ("svelte 5.51" → "svelte")
42
- const name = depName.split(' ')[0].toLowerCase();
43
-
44
- // Match diretto
45
- if (DOCS_REGISTRY[name]) return DOCS_REGISTRY[name];
46
-
47
- // Strip @scope/ prefix ("@sveltejs/kit" → "kit", ma usiamo mapping speciali)
48
- if (name === '@sveltejs/kit') return DOCS_REGISTRY['sveltekit'];
49
- if (name === 'next' || name === '@next/core') return DOCS_REGISTRY['next'];
50
-
51
- // Generic scope strip
52
- const stripped = name.startsWith('@') ? name.split('/')[1] : name;
53
- if (DOCS_REGISTRY[stripped]) return DOCS_REGISTRY[stripped];
54
-
55
- // Strip -js suffix ("solid-js" → "solid")
56
- const noJs = stripped.replace(/-js$/, '');
57
- if (noJs !== stripped && DOCS_REGISTRY[noJs]) return DOCS_REGISTRY[noJs];
58
-
59
- return null;
17
+ export async function lookupRegistryUrl(depName) {
18
+ if (!depName) return null;
19
+
20
+ // Normalizzazione preventiva
21
+ const name = depName.split(' ')[0].toLowerCase().trim();
22
+
23
+ // Check hit in memoria (ritorna subito)
24
+ if (lookupCache.has(name)) {
25
+ return lookupCache.get(name);
26
+ }
27
+
28
+ try {
29
+ // Fetch asincrono con timeout stretto per evitare latenze di fallback
30
+ const res = await fetch(`${REGISTRY_API_URL}?pkg=${encodeURIComponent(name)}`, {
31
+ signal: AbortSignal.timeout(1500), // Max 1.5s aspetta il Cloudflare worker
32
+ headers: {
33
+ 'Accept': 'application/json'
34
+ }
35
+ });
36
+
37
+ if (res.ok) {
38
+ const data = await res.json();
39
+ if (data && data.found && data.url) {
40
+ lookupCache.set(name, data.url); // Cache hit success
41
+ return data.url;
42
+ }
43
+ }
44
+
45
+ // Se l'API restituisce 404/not found
46
+ lookupCache.set(name, null); // Cache negative (così non rifacciamo network)
47
+ return null;
48
+
49
+ } catch (err) {
50
+ // Failover silente! (timeout o worker rotto). Se Cloudflare fallisce,
51
+ // noi non diamo errore all'utente ma facciamo DDG search fallback locale naturale.
52
+ lookupCache.set(name, null);
53
+ return null;
54
+ }
60
55
  }
61
-
62
- export { DOCS_REGISTRY };
package/src/search.js CHANGED
@@ -96,7 +96,7 @@ export async function registryFetch(deps, opts = {}) {
96
96
  const coveredDeps = new Set();
97
97
 
98
98
  for (const dep of deps) {
99
- const docUrl = lookupRegistryUrl(dep);
99
+ const docUrl = await lookupRegistryUrl(dep);
100
100
  if (!docUrl) continue;
101
101
 
102
102
  const depName = dep.split(' ')[0];