Skit SDK
API reference for @minato/skit, the TypeScript SDK for Minato scrapers.
Factory functions
import { defineScheduledScraper, defineDaemonScraper } from "@minato/skit";Export the result as your module's default export.
| Function | Use when |
|---|---|
defineScheduledScraper | run() does one pass and exits |
defineDaemonScraper | run() maintains a persistent connection |
Pass TConfig as a type parameter to type your config:
type Config = { maxPages: number; delayMs: number };
export default defineScheduledScraper<Config>({ ... });Context
run() receives a single context object:
| Property | Type | Description |
|---|---|---|
ingest | IngestClient | Buffer and flush torrents |
config | TConfig | Merged config (dashboard overrides applied) |
signal | AbortSignal | Aborted on pause or stop |
status | StatusReporter | Report progress to the dashboard |
meta | { id, name, version } | Scraper identity |
flaresolverr | FlareSolverr | Pre-configured Cloudflare bypass client |
ingest
ingest.add(torrent: TorrentInput): voidBuffers a torrent. Minato flushes in batches automatically; you never call flush() yourself. infoHash is the global deduplication key: the same hash is never stored twice, regardless of which scraper submitted it.
TorrentInput
| Field | Required | Type | Notes |
|---|---|---|---|
infoHash | ✅ | string | 40-char hex info hash |
title | ✅ | string | Release name |
size | ✅ | number | Total size in bytes |
source.name | ✅ | string | Label shown in the UI. Use meta.name. |
seeders | number | ||
leechers | number | ||
magnet | string | Full magnet URI | |
category | string | Tracker-specific category label | |
publishedAt | string | ISO 8601 | |
files | Array<{ filename, size }> | ||
source.url | string | Torrent detail page | |
source.origin | string | Tracker or index name | |
source.originUrl | string | Tracker homepage |
config
The result of merging minato.defaultConfig with any overrides the admin set in the dashboard. Dashboard values always win; you can't override them from code. Treat config as read-only at runtime.
const { maxPages, delayMs } = config;signal
Fires on both pause and stop. The scraper can't distinguish between them; that's Minato's concern. Check at loop boundaries and return cleanly when aborted.
for (const page of pages) {
if (signal.aborted) break;
// ...
}Buffered torrents flush automatically before exit. A paused scraper can be resumed on demand; a stopped one waits for its next scheduled run.
status
status.update({
phase?: "idle" | "running" | "paused" | "error",
progress?: { current: number; total?: number },
message?: string,
})All fields optional. Failed calls are silently ignored.
meta
meta.id // "my-scraper"
meta.name // "My Scraper"
meta.version // "1.0.0"Use meta.name as source.name in ingest.add() so the source label in the UI stays consistent with the dashboard name.
flaresolverr
A pre-configured FlareSolverr client for sites protected by Cloudflare. Use ffetch as a drop-in replacement for fetch, routing the request through FlareSolverr and returning a standard Response.
import { ffetch } from "@minato/skit";
export default defineScheduledScraper({
async run(ctx) {
const res = await ffetch(ctx, "https://protected-site.example/list");
const html = await res.text();
// parse and ingest...
},
});ffetch supports GET and POST only. It throws if FlareSolverr is unreachable or returns an error, so the failure surfaces as a normal scraper crash rather than silently producing empty results.