@appport/server

中文文档
1.3.0发布于 2026/11/06Apache-2.0TypeScriptES Module近 30 天下载 2191

Server-side AppPort protocol runtime with HTTP and WebSocket bindings.

原始使用文档
文档目录6 节
  1. Browser boundary modes
  2. Direct browser mode
  3. Trusted boundary mode
  4. Server mode
  5. Public discovery (1.1.0)
  6. Authenticating with permissionAuthorizer

@appport/server

The server-side protocol runtime and its web bindings.

import { createServer } from "@appport/server";
import { serve } from "@appport/server/node";

const server = createServer({
  application,
  authenticate: ({ sessionId }) => sessions.resolve(sessionId)
});

const running = await serve({ server, port: 4400, cors: { origins: "*" } });

A complete minimal provider needs nothing else for clients to connect: serve advertises, in the manifest and so in /.well-known/appport, the transports it actually binds (http at /appport, and websocket at /appport/ws unless you pass websocket: false), as same-origin paths. It never advertises an endpoint it does not serve. Pass advertise: false to advertise nothing, or transports to createApplication to advertise something else (for example a public URL behind a proxy). If an application advertises no transport, AppPort.discover fails with INVALID_PROTOCOL and says so.

serve exposes, against one capability server:

RoutePurpose
POST /appportrequests, and streams as NDJSON
GET /appport/eventsevents as Server-Sent Events
GET /appport/manifestthe manifest
GET /.well-known/appportdiscovery
WS /appport/wsthe WebSocket binding

The WebSocket endpoint is a dependency-free RFC 6455 implementation: framing, fragmentation, ping/pong and close, with one AppPort envelope per message.

AppPortConnection is the duplex half used by WebSocket, IPC and in-process transports. It owns subscription and stream bookkeeping, so unsubscribe releases resources and cancellation reaches the handler.

For edge runtimes, createFetchHandler(binding) returns a standard (Request) => Promise<Response>.

authenticate resolves an identity from transport-supplied credentials. AppPort does not authenticate; it represents the resulting identity, and authorizes every capability regardless of which transport delivered it.

Browser boundary modes

Direct browser mode

browser origin
  -> @appport/transport-http
  -> AppPort HTTP server with CORS/origin policy
  -> capability

Configure the HTTP binding with cors and allowedOrigins when the browser talks to the AppPort server directly.

Trusted boundary mode

browser
  -> same-origin AppPort server
  -> server-side AppPort client / transport
  -> remote capability

The trusted boundary authenticates the caller, authorizes the capability, applies origin policy, and uses server-side credentials for any downstream AppPort call. The browser never receives those trusted credentials.

Server mode

node/server
  -> @appport/transport-http
  -> remote AppPort capability

In every mode, CORS stays in the HTTP boundary. It is not part of the AppPort protocol.

Public discovery (1.1.0)

createServer({ application, publication }) opts into a public description served at /appport/public and advertised from /.well-known/appport. Absent, disabled, malformed or inconsistent policy publishes nothing. The manifest remains public by protocol, so "not published" is not "secret". Discovery is not authorization.

The policy has this shape (PublicationPolicy in @appport/protocol); nothing is published unless public is exactly true, and only the capabilities you name are listed:

publication: {
  public: true,
  applicationDescription: false, // optional: include the manifest's application description
  capabilities: [{ name: "tasks.add", version: 1, purpose: true }] // purpose: include that capability's description
}

A consumer's AppPort.discoverApplication result reports notPublishedCount: every manifest capability you did not name, including the built-in appport.manifest and appport.ping, so a provider that publishes one of three capabilities reports 4.

Authenticating with permissionAuthorizer

permissionAuthorizer() decides from the session's permissions, but only for an identified caller: an identity with no principal is treated as unauthenticated and gets UNAUTHORIZED ("Authentication is required"), not FORBIDDEN, even if it carries permissions. Return both from authenticate: { principal, session: { ..., principal, permissions } }. A caller that is identified but lacks a required permission gets FORBIDDEN.

版本与发布记录

@appport/server 共发布 13 个版本,首次发布于 2026/09/21;过去 12 个月发布了 13 个版本。

版本发布日期距今
1.3.0latest2026/11/062 天前
1.2.02026/11/052 天前
1.1.62026/11/034 天前
1.1.52026/10/2810 天前
1.1.42026/10/2217 天前
1.1.32026/10/1919 天前

关于 @appport/server 的常见问题

@appport/server 是什么?

Server-side AppPort protocol runtime with HTTP and WebSocket bindings.

如何安装 @appport/server?

在项目目录运行 npm install @appport/server,或使用 pnpm add / yarn add / bun add。

@appport/server 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@appport/server 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@appport/server 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@appport/server 可以商用吗?

@appport/server 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@appport/server 的下载量有多少?

根据 npm 官方下载统计,@appport/server 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,191 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@appport/server 还在维护吗?

最新版本 1.3.0 发布于 2026/11/06(2 天前);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/09/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。