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

@runko/conformance

v0.1.2

Published

runko 宿主能力的契约一致性套件——写了持久化或归属仲裁实现,拿它验合不合契约

Readme

@runko/conformance

runko 宿主能力的契约一致性套件。 写了一个持久化归属仲裁机制的实现,拿它验合不合契约。

接口注释里写死了一堆承诺——「同一个 seq 重复写入不得写出两行」「settle 对已结清的返回 false 而不是抛」「取号一律不抛错」——这个包把它们变成可执行的断言。runko 自己的五个官方实现跑的就是这一份。

它不依赖任何测试框架

套件只导出用例数据{ name, run }),describe / it 由你来接。所以 vitest / jest / node:test / Workers 上都能跑,装它也不会把某个测试框架拖进你的依赖树。

pnpm add -D @runko/conformance
import { persistenceCases } from "@runko/conformance";
import { describe, it } from "vitest";

describe("我自己的持久化实现", () => {
  for (const testCase of persistenceCases) {
    it(testCase.name, async () => {
      const setup = { persistence: myPersistence(), cleanup: () => myTeardown() };
      try {
        await testCase.run(setup);
      } finally {
        await setup.cleanup();
      }
    });
  }
});

每条用例都要一份干净的实现(空库 / 新实例),所以 makeSetup 放在 it 里面调,不要放在外面共用一个。

三组归属仲裁用例,按能力分开接

归属仲裁的实现能力不一样:内存版就在一个进程里,没有第二个节点、也没有「心跳超时」这回事;租约版才有。所以用例分三个数组,不是一个数组配可选字段——后者会让一个本该支持接管的实现漏传 expire静默跳过那几条还显示绿。

| 导出 | 谁跑 | 需要的 setup | | --- | --- | --- | | arbitrationCases | 所有实现 | { arbitration } | | arbitrationMultiNodeCases | 能表达两个节点的 | + other | | arbitrationTakeoverCases | 能表达超时接管的 | + expire |

import { arbitrationCases, arbitrationTakeoverCases } from "@runko/conformance";

跑了哪几组写在你自己的代码里,一眼可查。(三个数组之间没有类型绑定——少接一组编译照过,这条靠代码评审守。)

expire 要让持有者「持续」看起来死了。 只把心跳时刻拨到过去是不够的:持有者还活着,它下一拍心跳就把时刻刷回来了,接管会随机失败。要么让持有者那一侧的时钟停在过去,要么真的把它的心跳停掉。

断言失败长什么样

套件自带一套手写断言(连 node:assert 都不用,才能在任何环境里跑)。失败时抛 ConformanceAssertionError,带上 expected / actual,测试框架的 diff 视图直接能用:

ConformanceAssertionError: 结构不相等
  期望: {"ok":true,"seq":3}
  实际: {"ok":true,"seq":1}

文档

持久化 · 功能手册 · 持久化 · 技术方案 · 归属仲裁 · 技术方案