Files
mesh-catalog/modules/verdaccio/index.ts
T
jschoubben 81dc74734b registry, verdaccio, portainer: full nox modules (ADR 0044/0046)
registry (docker v2): catalog/tags/delete tools, emits image.pushed (a build's
image is now pullable). verdaccio (npm): list/info tools, emits
package.published. portainer: endpoints/stacks/containers tools — tools-only,
since its only events are the underlying containers' lifecycle, which the host
owns. Typecheck; manifests parse.
2026-09-04 02:45:42 +02:00

46 lines
1.9 KiB
TypeScript

// verdaccio's events. The tool runtime imports this once the broker is bound.
//
// Emits (novox/hq ADR 0046/0047):
// module.verdaccio.package.published — a new package version was published to the registry
//
// A genuinely useful signal: a package was just published, so anything on the mesh that pins,
// mirrors or announces dependency releases can react without polling the registry. Verdaccio has
// no publish webhook, so the module discovers it by diffing the package list's latest versions.
//
// The polling is deliberately unhurried: a publish a minute late is still the event, whereas
// hammering the registry for immediacy nobody asked for is not.
import { emit } from "@novox/mesh-sdk/events";
import { VerdaccioClient } from "./client.js";
const verdaccio = VerdaccioClient.fromEnv();
// The latest version we have seen per package name. Primed silently on the first look so a registry
// that was already populated when this started does not announce its whole catalog as freshly
// published.
const latest = new Map<string, string>();
let primed = false;
async function pollPackages(): Promise<void> {
const packages = await verdaccio.listPackages();
for (const pkg of packages) {
if (!pkg.version) continue;
const known = latest.get(pkg.name);
if (known !== pkg.version) {
// A name we have not seen, or a name whose latest version moved — both are a publish.
if (primed) await emit("module.verdaccio.package.published", { name: pkg.name, version: pkg.version });
latest.set(pkg.name, pkg.version);
}
}
primed = true;
}
const tick = (fn: () => Promise<void>, everyMs: number): void => {
const run = (): void => void fn().catch((err) => console.error(`[verdaccio] ${err}`));
setInterval(run, everyMs);
run();
};
tick(pollPackages, 60_000);
console.log("[verdaccio] watching the registry for newly published packages");