npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@suluk/provision

v0.3.0

Published

Declarative service provisioning for a Suluk app, modelled on the Open Service Broker API and driven like drizzle-kit. Declare the infra you want in one provision.config (D1/KV/R2/secrets/Stripe/domains/tokens as OSB brokers); `plan` diffs desired-vs-live

Readme


CANDIDATE tooling — not official OpenAPI. Suluk is a single-contributor candidate for OpenAPI Specification v4.0 ("Moonwalk"), unaffiliated with the OpenAPI Initiative and unable to ratify anything on the SIG's behalf.

Install

bun add @suluk/provision

What it does

Infrastructure as a declarative config, modelled on the Open Service Broker API and driven like drizzle-kit (C047). You list the instances you want — each an OSB broker plus a name, plan, params, and binding map — and the lifecycle is a pure function of that config × live state:

  • plan diffs desired-vs-live into a reviewable list of steps (create / update / noop / deprovision), in binding-DAG order. Pure: no provider calls, no clock.
  • apply walks that DAG and calls the OSB verbs — provision (idempotent) → poll async lastOperation until a create settles → bind for credentials → land them in a BindingSink (the @suluk/env manifest in prod). A downstream @ref.key param resolves to a freshly provisioned value, so the DAG wires itself.
  • checkDrift / assertNoDrift is the CI gate (a clean plan ⇒ no drift).

A param of the form @<ref>.<key> is a binding reference — that's what makes db provision before the token that scopes to @db.database_id. defineProvision validates the static shape (unique refs, an acyclic binding DAG) at authoring time, so a loop or an unreferenceable ref is caught before any provider is called. Stateful resources can be protected (the terraform prevent_destroy analog). A drizzle-style snapshot + migration model gives repeatable, documentable steps.

Usage

import {
  defineProvision, plan, apply, assertNoDrift,
  memoryStore, memorySink,
  cloudflareD1, cloudflareToken,
} from "@suluk/provision";

// Declare the infra. `@db.database_id` wires the token AFTER the D1 database.
const config = defineProvision({
  instances: [
    { ref: "db", service: "cloudflare-d1", name: "app-db", protected: true, bind: { database_id: "CLOUDFLARE_D1_ID" } },
    { ref: "token", service: "cloudflare-token", name: "d1-token",
      params: { scope: "@db.database_id" }, bind: { token: "CLOUDFLARE_D1_TOKEN" } },
  ],
});

// The concrete Cloudflare brokers wrap @suluk/cloudflare's idempotent provisioners.
const brokers = { "cloudflare-d1": cloudflareD1(cf), "cloudflare-token": cloudflareToken(cf) };
const store = memoryStore();  // a JSON file in prod (`fileStore`)
const sink = memorySink();    // the @suluk/env manifest in prod (`envSink`)

// Review, then execute along the binding DAG.
const state = await store.load();
console.table(plan(config, state).steps); // [{ ref, action, reason }, …]

const result = await apply(config, { brokers, store, sink });
result.outputsByRef.db; // { database_id: "…" } — resolved outputs after the run

// CI gate: throw if the live infra has drifted from the config.
await assertNoDrift(config, await store.load());

CLI

suluk-provision plan     # diff desired-vs-live
suluk-provision apply    # provision → bind → land credentials
suluk-provision check    # drift / orphan gate (CI)
suluk-provision status

What's inside

| Export | What it does | | --- | --- | | defineProvision(config) | Validate + return the config (throws on dup/unknown ref or a cycle). | | plan(config, state, prune?) | The pure diff → ProvisionPlan (steps, orphans, clean). | | apply(config, opts) | Execute a plan along the binding DAG → ApplyResult (with resolved outputs). | | checkDrift / assertNoDrift | Drift report + the CI gate. | | pull / reconcile / discover | Read live state back; adopt un-tracked instances. | | teardown | Deprovision (skips protected unless forced). | | topoOrder, parseRef, depsOf, resolveParams, fingerprint | The binding-DAG + ref-resolution internals. | | snapshot / diffSnapshots / migrate / generate | The drizzle-style snapshot + migration model. | | memoryStore / fileStore, memorySink / envSink | The state store + binding sink (dev/test vs prod). | | cloudflareD1 / cloudflareKv / cloudflareR2 / cloudflareSecrets / cloudflareToken / cloudflarePagesDomain | The concrete Cloudflare brokers. | | defineProvisionApp, runCli | The drizzle-kit-style app config + CLI. |

Types Broker, BindingSink, StateStore, Catalog, InstanceSpec, InstanceState, and the OSB request/result shapes are exported alongside.

Boundary

@suluk/provision is the OSB client / orchestrator — a layer above @suluk/cloudflare (the idempotent provisioners it wraps as brokers), @suluk/deploy, and @suluk/env (the binding sink). It orchestrates; they execute. Provider calls live in the brokers; the core is pure orchestration over them, with the clock and sleep injected so apply is deterministically testable. It's the lower half of @suluk/platform, which merges each module's provision fragment into one config.

License

Apache-2.0