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

@pluxel/wretch

v1.0.0

Published

Official Wretch outbound HTTP capability for Pluxel plugins

Readme

@pluxel/wretch

Pluxel 官方出站 HTTP 插件,基于 Wretch。插件提供一个带宿主级 outbound policy 的原生、不可变 Wretch base;请求构造、addon、middleware、catcher 和 response chain 仍 完全使用 Wretch API。

使用

pnpm add @pluxel/wretch @pluxel/runtime

把 WretchPlugin 放进宿主 catalog,需要 HTTP 的插件通过 constructor 声明 required dependency:

import { BasePlugin, Plugin, v } from '@pluxel/runtime'
import { WretchPlugin, type Wretch } from '@pluxel/wretch'

type Customer = { id: string; name: string }

const CustomerConfig = v.object({
	baseUrl: v.pipe(v.string(), v.url()),
})

@Plugin()
export class CustomerPlugin extends BasePlugin {
	private readonly config = this.configs.use(CustomerConfig)
	private api!: Wretch

	constructor(private readonly http: WretchPlugin) {
		super()
	}

	override init(): void {
		this.api = this.http.client.url(this.config.baseUrl, true)
	}

	find(id: string) {
		return this.api.get(`/customers/${encodeURIComponent(id)}`).json<Customer>()
	}
}

client 本身就是 Wretch。Wretch 的 immutable 语义保证不同 consumer 从同一个 base 派生 .url()、 .options()、.headers()、.auth()、.addon() 或 .middlewares() 时不会互相污染。

主入口只导出 WretchPlugin 和 Wretch 类型,不重新导出裸 wretch() factory 或 addon/middleware。 创建不受宿主 policy 管理的普通 Wretch 时应直接使用上游 wretch 包。

需要 retry、dedupe、query string 或其他扩展时直接使用 Wretch 原生模块:

import QueryStringAddon from 'wretch/addons/queryString'
import { retry } from 'wretch/middlewares'

this.api = this.http.client
	.url(this.config.baseUrl, true)
	.addon(QueryStringAddon)
	.middlewares([retry({ maxAttempts: 2, retryOnNetworkError: true })])

如果 consumer 直接导入 Wretch 的 addon/middleware,请把 wretch 声明为自己的 dependency,以明确所用 原生 API 的版本。

宿主级 policy

WretchPlugin 的 Pluxel config 会自动进入标准 Config UI:

| 字段 | 默认值 | 含义 | | ----------------------- | ------ | --------------------------------------------------- | | timeoutMs | 30000 | 每次实际 fetch attempt 的超时;0 表示关闭 | | maxConcurrentRequests | 64 | 所有 consumer 共用的实际 fetch attempt 上限 | | maxQueuedRequests | 256 | 并发满时允许等待的 attempt 数 | | allowedOrigins | [] | 空列表不限制;非空时只允许列出的精确 HTTP(S) origin |

policy 使用一个 deferred Wretch middleware 安装:consumer 先完成自己的 immutable chain 组合,请求发送前 provider middleware 才被追加到末尾。因此 consumer 的 retry middleware 位于外层,每次 retry attempt 都会 单独经过 origin、admission 和 timeout,而不是让一个逻辑请求长期占用并发槽。

.fetchPolyfill() 仍按 Wretch 原生语义工作,并且不会绕过 provider middleware,适合测试或自定义 fetch boundary。只有显式清空 deferred callbacks 才会移除 provider policy,不应在受管 client 上这样做。

client 与取得它的 consumer/provider lifecycle generation 绑定。任一方 stop 或 replacement 后,缓存的旧 client 会拒绝新请求,等待并发槽的请求会被解除排队;已经进入 fetch 的请求会收到 lifecycle abort signal。自定义 fetch 需要遵守标准 AbortSignal,才能在 teardown 时立即结束。

retry、dedupe、缓存、鉴权刷新和业务错误解析不属于进程级安全不变量,插件不会替 consumer 决定。需要缓存 时显式组合 @pluxel/cache。

可选 Workbench 配置 UI

WretchPlugin 提供 provider-owned WretchWorkbench.settings Attachment。consumer 只选择 placement, 不实现表单 renderer,也不转发 RPC:

import { workbench } from '@pluxel/runtime/workbench'
import { WretchWorkbench } from '@pluxel/wretch/workbench'

export const CustomerWorkbench = workbench.define({
	http: WretchWorkbench.settings.place(
		workbench.tab({ label: 'HTTP', icon: workbench.icons.Settings }),
	),
})

consumer 启动时显式启用持久化设置,再把 constructor-injected direct required dependency 绑定为 Attachment provider:

override async init(): Promise<void> {
	await this.http.enableManagedSettings()
	this.api = this.http.client.url(this.config.baseUrl, true)

	this.ctx.workbench?.publish(CustomerWorkbench, {
		http: { provider: this.http },
	})
}

provider publication 只在 View 实际打开时,从 server-derived consumer.node 找到已启用的 exact consumer state,并创建 fresh WretchSettingsApi root。browser renderer 使用 descriptor-bound settingsScope,由 query/mutation resources 取得 { provider }、自动 detach snapshot() / update() / reset() 的 DTO,并在写入 settle 后刷新 snapshot。

UI 当前统一管理:

  • 会覆盖 consumer 同名普通 header 的运行时请求头;
  • HTTP(S) proxy;
  • 只能收紧宿主上限的 consumer timeout。

设置按 caller 的结构化 Plugin node address 隔离:文件名只使用 canonical address bytes 的完整 SHA-256,文件内容同时保存并 校验完整 owner address。displayName 相同的 Plugin/fork 不会冲突;只接受当前 v2 envelope,并存储在 consumers/v3。client 使用 Wretch defer() 在每次请求发送前读取当前设置,因此保存后 已经缓存的 client 也会自动生效,不需要重建。 同一 caller 并发调用 enableManagedSettings() 会共享一次初始化;已打开的 settings capability 在 caller/provider stop、replacement、View close 或 session end 后撤销,不能继续写入旧 generation。provider cleanup 也会主动释放全部 managed ProxyAgent,不依赖 consumer 必须级联停止。

Authorization、Cookie、Proxy-Authorization、X-API-Key,以及带路径或凭据的 proxy URL 会被拒绝。 当前设置页不支持 authenticated proxy;secret 不进入普通 persistence、日志或 browser contract。 Workbench disabled 时不会创建 UI backend;consumer 已选择启用的持久化设置仍会应用于核心 HTTP client。

实现边界见 DESIGN.md。