cyberlink
v2.6.0
Published
High-performance link harvester — 100k+ unique URLs, Playwright-powered, cookie auth for social platforms
Maintainers
Readme
CYBERLINK
Installation
npm install cyberlinkUsage Example
import { cybersearch } from "cyberlink";
const query = "drake";
const result = await cybersearch(query, { sources: true, limit: 5 });
console.log(results);
});AI SUMMARY (Optional)
console.log("=== aiSummary ===\n");
try {
const { summary } = await aiSummary(results, {
model: "llama-3.1-8b-instant",
apiKey: process.env.GROQ_API_KEY,
});
console.log("Summary:", summary);
} catch (err) {
console.error("[aiSummary] failed:", err?.message ?? err);
}Putting it all together
/**
* test.js — cyberlink v2
* Run: node test.js
*/
import { cybersearch, streamResults, aiSummary, screenshot } from "./dist/index.js";
import { writeFileSync } from "fs";
import dotenv from "dotenv";
dotenv.config();
const DIV = "─".repeat(72);
const DIV2 = "═".repeat(72);
const PREVIEW = 600;
function showResult(r, i) {
const source = (() => { try { return new URL(r.url).hostname.replace("www.", ""); } catch { return r.url; } })();
console.log(`\n${DIV}`);
console.log(`[${i + 1}] ${r.title}`);
console.log(` Source: ${source}`);
if (r.thumbnail) console.log(` Thumb: ${r.thumbnail}`);
console.log();
const content = r.context?.trim() ?? "";
if (content.length > 20) {
console.log(content.slice(0, PREVIEW));
if (content.length > PREVIEW)
console.log(`\n ... (${content.length.toLocaleString()} chars total)`);
} else {
console.log(" (no text content)");
}
}
// ── Test 1: Open API sources ──────────────────────────────────────────────
console.log(`\n${DIV2}`);
console.log("TEST 1 — Open API sources (Wikipedia, Guardian, Reddit, HN, GitHub)");
console.log(DIV2);
const q = "climate change";
console.log(`Query: "${q}"\n`);
const apiResults = await cybersearch(q, { lim: 8, sources: true });
if (apiResults.length === 0) {
console.log("No results.");
} else {
apiResults.forEach(showResult);
console.log(`\n${DIV}\n✅ ${apiResults.length} results\n`);
}
// ── Test 2: Direct URL scrape — Reuters article (good HTML, no JS wall) ──
console.log(`\n${DIV2}`);
console.log("TEST 2 — Direct URL scrape (Reuters)");
console.log(DIV2);
// Reuters is confirmed scrapable from the reference doc — static HTML, real content
const scraped = await cybersearch("https://www.reuters.com/sustainability/climate-energy/");
if (scraped.length === 0) {
console.log("No content extracted — trying AP News instead...");
const scraped2 = await cybersearch("https://apnews.com/hub/climate-and-environment");
if (scraped2.length > 0) {
const r = scraped2[0];
console.log(`\nTitle: ${r.title}`);
console.log(`Chars: ${r.context.length.toLocaleString()}`);
console.log("\n--- First 600 chars ---\n");
console.log(r.context.slice(0, 600));
} else {
console.log("Both scrape targets returned no content.");
}
} else {
const r = scraped[0];
console.log(`\nTitle: ${r.title}`);
console.log(`Chars: ${r.context.length.toLocaleString()}`);
if (r.thumbnail) console.log(`Image: ${r.thumbnail}`);
console.log("\n--- First 600 chars ---\n");
console.log(r.context.slice(0, 600));
}
// ── Test 3: Stream — live content as it arrives ───────────────────────────
console.log(`\n${DIV2}`);
console.log("TEST 3 — streamResults (content printed as it arrives)");
console.log(DIV2);
const q2 = "nodejs performance tips";
console.log(`Query: "${q2}"\n`);
let n = 0;
const t0 = Date.now();
for await (const event of streamResults(q2, { lim: 4, sources: true })) {
if (event.type === "result") {
n++;
const r = event.result;
const host = (() => { try { return new URL(r.url).hostname.replace("www.", ""); } catch { return ""; } })();
const preview = r.context?.trim().slice(0, 300) ?? "(no content)";
console.log(`\n[+${Date.now() - t0}ms] #${n} ${r.title} (${host})`);
console.log(preview);
}
if (event.type === "done")
console.log(`\n${DIV}\n✅ ${event.results.length} results in ${Date.now() - t0}ms`);
}
// ── Test 4: Screenshot ────────────────────────────────────────────────────
console.log(`\n${DIV2}`);
console.log("TEST 4 — Screenshot");
console.log(DIV2 + "\n");
try {
const png = await screenshot("https://apnews.com/hub/climate-and-environment", {
width: 1280, height: 900, waitUntil: "domcontentloaded",
});
writeFileSync("climate-screenshot.png", png);
console.log(`✅ climate-screenshot.png (${(png.length / 1024).toFixed(1)} KB)`);
} catch (err) {
console.error("Screenshot failed:", err.message);
}
// ── Test 5: AI summary ────────────────────────────────────────────────────
if (process.env.GROQ_API_KEY && apiResults.length > 0) {
console.log(`\n${DIV2}`);
console.log("TEST 5 — AI Summary (Groq)");
console.log(DIV2 + "\n");
try {
const { summary } = await aiSummary(apiResults, {
groq_api_key: process.env.GROQ_API_KEY,
groq_model: "llama-3.1-8b-instant",
});
console.log(summary);
} catch (err) {
console.error("aiSummary failed:", err.message);
}
} else {
console.log("\n(Set GROQ_API_KEY in .env to enable AI summary)");
}