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

@modules.services/midway-tool

v3.6.0

Published

模块服务工具层

Readme

@modules.services/midway-tool

Tool.ms:transport、超时与负载限制

语义(重要)

  • **transport: 'auto'(默认)或未写**:若已配置 ms.reg.*.grpc,默认按 **msAutoFallback依次尝试 **grpch2streamhttp(仅当上一层返回「传输层可重试」类结果时才进入下一层,例如 gRPC 404、超时类 400、负载 413 等;远程业务 401 等不会盲目降级)。未配置 grpc 时链退化为 **['http']**。配置 **ms.msAutoFallback: false**(或 options.msAutoFallback)可恢复旧行为:auto 时只试 gRPC或只走 HTTP,不在协议间切换。
  • **msAutoFallback**:true 或未设时等同上述默认顺序;亦可传数组自定义顺序,如 ['grpc','http'] 跳过 h2;[]false 一样表示关闭链式降级。
  • **transport: 'grpc'**:强制 gRPC;未配置 grpc 地址时返回 402
  • **transport: 'h2stream' | 'http2'**:走 HTTP 分片并发传输(init/uploadPart/complete/abort),适合 gRPC 连接不稳定场景。
  • **transport: 'http'**:仅 HTTP。
  • **strictTransport**optionsms.strictTransport):非法 transport 字符串时返回 400;否则兼容旧行为并 warn,按 HTTP 调用。

超时(HTTP 与 gRPC 一致)

  • ms.reg.<name>.timeout 优先,否则 ms.timeout,否则 10(秒)
  • HTTP:作为 axios timeout(毫秒) = max(1000, seconds * 1000)
  • gRPC:streamInvoke{ timeout } + 单次调用的 wall-clock Promise.race,与上式同一套秒数换算。

Payload 限额(先发制人,超限不发起请求)

估算基于 单次 AES2('encrypt', payload) 后的体积:

  • HTTP:按 **JSON.stringify({ data: enc, keys }) 的字节长度**。默认限额优先读取应用合并配置中的 bodyParser.jsonLimit(与 @modules.services/framework 等根配置里的 bodyParser 一致,例如 '5mb'),这样 Tool.ms 侧不会在「已超过 bodyparser」的情况下仍发起 POST。若未配置或无法解析,则使用库内兜底 48MB。仍可通过 ms.msHttpMaxPayloadBytes / options.msHttpMaxPayloadBytes 显式覆盖。
  • gRPC:按 密文字符串 UTF-8 字节数(流式正文合计);默认 62MB,对齐客户端 grpc.max_*_message_length 64MB。可配 ms.msGrpcMaxPayloadBytesmsGrpcMaxPayloadBytes

超限返回 **code: 413**,message 中含估算字节数、限额与分批建议。

gRPC 重试(可选)

  • **msGrpcMaxRetries**:在 msoptions 上配置,表示 额外重试次数(不含首次),默认 0
  • **msGrpcRetryableStatusCodes**:默认可重试:UNAVAILABLEDEADLINE_EXCEEDEDRESOURCE_EXHAUSTED
  • 重试前会 invalidate 对应 grpcUrl 的 stub 缓存,便于下次重建连接。
  • 失败日志为一行结构化 JSON:event=ms_grpc_failuretargetqueryMsgrpcCodeattemptwillRetry 等。

单帧大小

  • msGrpcChunkSize(或 chunkSize)不得超过 **msGrpcMaxMessageBytes**(可选;未设则按 64MB 客户端上限校验)。

HTTP2 分片并发(h2stream)

  • 接口:/__MicroService__/h2/init/__MicroService__/h2/uploadPart/__MicroService__/h2/complete/__MicroService__/h2/abort
  • 字段:uploadIdpartNototalPartschecksum(sha256)idempotencyKeyexpiresAt
  • 服务端落盘目录:$TMPDIR/midway-ms-h2/<uploadId>/(分片文件 + meta.json),避免“整包全内存拼接”。
  • 客户端配置:msH2PartSizemsH2ConcurrencymsH2SessionTTLSeconds
  • 单片重试:msH2PartMaxRetriesmsH2PartRetryBaseMs(指数退避,失败片可独立恢复)。
  • complete 补片闭环:客户端 complete 前本地自检缺片;若服务端 complete 返回 missingParts,客户端按清单补传后自动重试 complete(msH2CompleteMissingRetryRounds 控制轮次)。
  • 存储模式:msH2Store = 'disk' | 'objectStorage'(当前 objectStorage 为本地仿真语义,已预留后续接 OSS SDK)。

微服务名类型同步(类 eps / 远端 manifest → 本地补全)

目标this.tool.ms('module.method') 在 IDE 中有字面量补全。TypeScript 只认磁盘上的类型,因此采用「提供方 HTTP 暴露清单 → 调用方写成 .d.ts(随 Tool 包启动自动同步或 CLI)→ declare module 合并 MicroServiceNameMap」。

提供方(本库已内置)

  • ms.offer 中注册 class 后启动应用,与现有 __MicroService__ 同条件挂载 Controller。
  • GET /<prefix>/registry-manifest(与 __MicroService__ 一致时为 **GET /__MicroService__/registry-manifest**)
  • 返回 JSON(与 Tool.ms 加解密无关,无需 x-ms-k):
{
  "code": 200,
  "message": "ok",
  "data": {
    "schemaVersion": 1,
    "manifestVersion": "<sha256 hex,64 字符,由当前全量可调服务名动态计算>",
    "generatedAt": "2026-05-04T12:00:00.000Z",
    "total": 2,
    "names": ["user.getDetail", "user.getList"],
    "modules": { "user": ["getDetail", "getList"] }
  }
}
  • 版本(与 offer 内容绑定)无需手写版本号manifestVersion 为当前扫描得到的全量 module.method 名称列表(排序后逐行拼接)的 SHA256 十六进制(64 字符);只要 ms.offer可调用的方法名增删,hash 即变化。仅修改方法实现而不改方法名时,hash 不变(与“仅按对外接口名做类型补全”一致)。调用方 ***.sync.json** 中保存同一字符串,与提供方一致即视为无需再拉。
  • 省流探针**GET ...?metaOnly=1**(可再带 key)返回 { schemaVersion, manifestVersion, generatedAt, total, paramsByNameCount }names;调用方将 paramsByNameCount 与本地 .sync.json 内同名字段比对,manifestVersion 一并用于判断是否跳过全量拉取(避免版本号相同但 params 层刚就绪时仍跳过 typings 更新)。
  • 分页(协议能力,非手工流程):接口支持 **limit** / **offset,供 sync-ms-registry-dts 脚本在内部自动拼接;业务侧不需要自己循环拉取。返回中带 **total**hasMore**、**nextOffset** 及当前页 **modules**。单次 **limit****ms.msRegistryPageMax**(默认 10000)封顶。
    • 不传 limit:一次响应中带全量 names(小清单或调试方便);大批量场景请只使用下方同步脚本,由脚本自动分页,避免单次响应体过大。
  • 清单由 **ms.offer 的 class 上 public 方法** 扫描得到(与 user.* 列表逻辑一致);new 失败时回退为仅读 prototype
  • 可选安全:配置 **ms.msRegistryManifestKey** 后,须带查询参数 **?key=<同值>** 或请求头 **x-ms-registry-key**。生产环境建议开启或内网限制访问。
  • 关闭接口:ms.msRegistryManifestEnabled: false(返回 404)。
  • 网关/Nginx 可对 GET …/registry-manifest 开启 gzip,进一步减小传输体积。

调用方(业务工程)

底层仍是:把远端清单写成仓库里的 .d.ts(TypeScript 不能凭空从网上推断类型)。分页、metaOnly、hash 比对均由库内 **runMsRegistryClientSync** 统一完成,无需手写 limit/offset 循环

方式一(推荐):进程启动时自动同步——日常无需敲命令

  1. tsconfig.jsoninclude 包含生成目录(如 typings/**/*.d.ts)。
  2. 调用方 **imports 仅需引入 @modules.services/midway-tool(与现有做法一致)**,无需单独挂载其它 Configuration。
  3. **ms** 块中配置 **ms.reg**(调用方已有)与 **ms.msRegistryClientSync**。清单地址由 ms.reg 某一条 推导:host 优先(支持 http(s):// 或裸 host:port);若无可用 host 则用同条的 grpchost:port 或仅主机名,未写端口时与 Tool 一致默认 :55555),再在前缀补上 http://https://(端口为 443 时),最后拼接 **/__MicroService__/registry-manifest**。一般只需 ms.reg 里一项 + msRegistryClientSync.enabled: true
ms:
  reg:
    platform:
      enable: true
      host: http://127.0.0.1:7001   # 或与 grpc 二选一 / 互补(见上文)
      mk: your-mk-if-needed
  msRegistryClientSync:
    enabled: true

多条 ms.reg 时默认按 key 字典序用第一条能解析出地址的条目;极少场景可用嵌套配置里的 regKey 或环境变量 MS_REGISTRY_SYNC_FROM_REG 指定键名。

可选覆盖:顶层 **msRegistryClientSync.registryManifestUrl**(或与 **ms.msRegistryClientSync** 合并,嵌套优先),或环境变量 **MS_REGISTRY_SYNC_URL**

应用 **npm run dev / npm start** 且提供方可达时,ToolConfigurationonReady 自动拉清单并写入默认路径 **typings/microServiceNames.generated.d.ts** 与同目录 ***.sync.json**

  • 生产环境:默认 **NODE_ENV=production** 时不自动写 typings(避免多副本重复请求);需要时在 **ms.msRegistryClientSync****skipInProduction: false**
  • 仅用环境变量MS_REGISTRY_AUTO_SYNC=1,且 **MS_REGISTRY_SYNC_URL**;或与 **ms.reg** 联用 **MS_REGISTRY_SYNC_FROM_REG=<键名>**
  • 密钥:清单请求参数 **key** 优先顺序为 **ms.msRegistryClientSync.key** → 所选 **ms.reg 条目的 mk****MS_REGISTRY_KEY**(与提供方 **ms.msRegistryManifestKey** 对齐时使用)。
  • IDE:生成/更新 .d.ts 后若补全未刷新,可「TypeScript:重启 TS 服务」或重载窗口。

方式二:CLI(CI、或与启动解耦时使用)

**npm run build** 本包(CLI 依赖 **dist/lib/msRegistryClientSync.js**),再:

pnpm exec sync-ms-registry-dts -- --url http://127.0.0.1:7001/__MicroService__/registry-manifest --out typings/microServiceNames.generated.d.ts

逻辑与方式一相同;支持 **--input 本地 JSON**、--forceMS_REGISTRY_PAGE_SIZE 等。

角色对照

| 角色 | 是否要手动敲同步命令 | | --------- | ------------------------- | | 服务提供方 | ,启动即有清单接口。 | | 调用方 | (若已用方式一);否则用方式二或 CI。 |

超大清单:几千条名称会产生较大的 .d.ts,一般 IDE 可承受。

合并后的声明作用于 **MicroServiceNameMap**,Tool.ms 首参可收窄;建议将 **typings/*.d.ts** 纳入版本库或与 CI 约定生成时机。

清单还可携带 paramsByName(各 module.method 对应 opt.params 的 TS 对象字面量)。同步后会写入调用方 typings/*.generated.d.ts 中的 MicroServiceMethodParamsTool.ms 第二参随方法名收窄。

提供方如何生成 paramsByName(无需业务配置):在进程工作目录下若存在 tsconfig.json源码,库会用 ts-morph 扫描 ms.offer 中各类的首参类型并解析 params 字段,自动填入清单。若启动时 process.cwd() 不在项目根(例如在 dist/、PM2 子目录),请设置环境变量 MS_REGISTRY_SCAN_ROOT 指向含 tsconfig.json 与源码的根目录,否则会解析不到类定义,paramsByName 为空。若部署环境 仅有 dist/、无 .ts,请在构建阶段生成 registry-manifest-params.json(或 dist/registry-manifest-params.json),格式为 { "module.method": "{ key?: type }" }{ "paramsByName": { ... } };进程启动时会自动合并进清单(亦可通过 MS_REGISTRY_PARAMS_FILE 指定路径)。合并优先级:源码解析 优先于 缓存文件 优先于 Function#toString 兜底

调用方排查(没有生成 typings / 提供方看不到清单请求)

  1. 是否开启同步:必须 ms.msRegistryClientSync.enabled: true(或 MS_REGISTRY_AUTO_SYNC=1);仅有 ms.reg 不会自动写 typings。键名须为 enabled(库内已将误写的 enable 映射为 enabled)。
  2. 配置是否被读到:同步读的是 全局合并配置(与 Tool.ms 运行时一致)。若曾写在其它层级导致未合并,请确认业务的 config.default / 环境配置msms.msRegistryClientSync 确实加载(启动日志里应出现 [MsRegistryClientSync] 成功、跳过版本、或明确 warn)。
  3. 生产环境:默认 NODE_ENV=production 跳过写盘;本地开发勿误设 production,或设 skipInProduction: false
  4. 输出路径:默认在进程 cwdtypings/microServiceNames.generated.d.ts;若从非项目根目录启动(部分 PM2/脚本),文件会出现在 cwd/typings,用全局搜索 microServiceNames.generated 定位;或通过 ms.msRegistryClientSync.out 指绝对路径。
  5. 清单 URL:解析失败时日志为 未配置清单 URL...,请检查 ms.reghost / grpc 或显式 registryManifestUrl
  6. 生成的 typings/*.generated.d.ts:须在 declare module '@modules.services/midway-tool' 之前包含 import '@modules.services/midway-tool';(或 export {};)。若为纯 declare module,会 遮蔽 包导出并触发 TS2305/TS2322。同步写入前库内会再跑一次 ensureMsRegistryTypingsAugmentsPackage,自动补上 import(仍建议升级本包,勿依赖旧 CLI)。
  7. (备选)若 imports: [tool] 仍报 TS2322:改用 imports: [midwayToolImports](与 import { midwayToolImports } from '@modules.services/midway-tool'tool.midwayToolImports 配合),与 Midway 期望的 { Configuration } 形态完全一致。

手写补充

若个别名字未进 manifest,可在业务里再建一个 typings/ms-handwritten.d.ts 合并同一块 interface MicroServiceNameMap;补 params 时合并同一模块内的 interface MicroServiceMethodParams