@nilejs/client

中文文档
1.0.1发布于 2026/11/02TypeScriptESM + CJS

Standalone, type-safe client for Nile backend framework

原始使用文档
文档目录15 节
  1. Features
  2. Installation
  3. Usage
  4. 1. Create a Client
  5. 2. Invoke Actions
  6. 3. Full Type Safety (Recommended)
  7. 4. Discovery & Reflection
  8. API
  9. createNileClient<T>(config)
  10. Methods
  11. Nile 1.0.3 responses
  12. Socket.IO actions and topics
  13. Uploads
  14. Compatibility
  15. License

@nilejs/client

A type-safe frontend client for Nile Js backends.

Features

  • Type-safe: Consumes shared or CLI-generated backend types for service, action and payload checking.
  • Graceful Error Handling: Returns the same Result pattern as the Nile Js backend (isOk, isErr, value, error) instead of throwing exceptions.
  • Small: HTTP calls use the platform fetch. The only runtime dependency is socket.io-client, for the socket client.
  • Flexible: Supports custom headers, credentials, and timeouts per request.

Installation

# Using npm
npm install @nilejs/client

# Using pnpm
pnpm add @nilejs/client

# Using bun
bun add @nilejs/client

Usage

1. Create a Client

import { createNileClient } from "@nilejs/client";

const nile = createNileClient({
  baseUrl: "http://localhost:8000/api",
  credentials: "include",
});

2. Invoke Actions

const result = await nile.invoke({
  service: "tasks",
  action: "create",
  payload: { title: "Buy milk" },
});

if (result.isErr) {
  console.error("Action failed:", result.error);
} else {
  console.log("Success:", result.value);
}

Generate your types using the Nile CLI: nile generate schema --output ./src/generated

Then use the generated ServicePayloads map:

import { createNileClient } from "@nilejs/client";
import type { ServicePayloads } from "./generated/types";

const nile = createNileClient<ServicePayloads>({ 
  baseUrl: "/api" 
});

// Full autocomplete and type-checking for service, action, and payload
await nile.invoke({
  service: "tasks",
  action: "create",
  payload: { title: "Buy milk" }
});

4. Discovery & Reflection

// Explore services and actions
const services = await nile.explore({ service: "*", action: "*" });

if (services.isOk) {
  console.log(services.value);
}

// Fetch action schemas
const schemas = await nile.schema({ service: "tasks", action: "*" });

if (schemas.isOk) {
  console.log(schemas.value);
}

API

createNileClient<T>(config)

Returns a Nile client instance.

  • config.baseUrl: The base URL of your Nile API (e.g., http://localhost:8000/api).
  • config.credentials: Request credentials (include, omit, same-origin).
  • config.headers: Global headers to include in every request.
  • config.timeout: Default request timeout in milliseconds (default: 30000).

Methods

All methods return a Promise<ClientResult<T>>. Calls never throw:

  • Success: { isOk: true, isErr: false, value: T, error: null, message? }, where message is the server's success message for HTTP calls
  • Failure: { isOk: false, isErr: true, value: null, error: string, details }, where details holds any data the server attached, such as validation issues. Network failures and timeouts arrive as failures too.

Check isErr first, then read error or value. The older data field is still present as a deprecated alias (the value on success, null on failure) so existing code keeps working.

  • invoke(params): Execute a specific service action.
  • explore(params): Discover services/actions using wildcards.
  • schema(params): Fetch action schemas as JSON Schema.

Pass per-call settings in fetchOptions. Headers merge with the client’s configured headers; a per-call value overrides the same header regardless of case. Both Headers instances and header tuples are supported. The timeout covers reading the response body as well as connecting; an optional signal can cancel the call.

const controller = new AbortController();
const result = await nile.invoke({
  service: "tasks",
  action: "create",
  payload: { title: "Ship the next feature" },
  fetchOptions: {
    headers: { Authorization: "Bearer your-session-token" },
    timeout: 5000,
    signal: controller.signal,
  },
});

Nile 1.0.3 responses

HTTP responses contain exactly status, message and data. The client maps those into its existing Result API; it preserves custom messages, Zod’s prettified validation message, and generated diagnostic references. The default success message is Action completed.

For a validation failure, result.error is the readable message and result.details contains { errorCode, issues }. ValidationFailureData is exported for applications that narrow this unknown failure data. Other failures can carry different details, so check the shape before using it. Diagnostic failures may include Error Code: <unique-code> - <message> in the message. Treat the code as a reference to share with your backend logs; do not use it as a fixed error category.

Socket.IO actions and topics

Create a separate socket client. It owns the connection; you do not pass a socket into each invocation. Use shared types, generated action types, or define your frontend contracts explicitly. Topic definitions and authorization policies must also be configured on the backend.

import { createNileSocketClient } from "@nilejs/client";
import type { ServicePayloads } from "./generated/types";

type Topics = {
  "tasks.changed": {
    data: { taskId: string; status: string };
  };
};

const socket = createNileSocketClient<ServicePayloads, Topics>({
  baseUrl: "http://localhost:8000",
  auth: () => {
    return { token: "your-session-token" };
  },
});

const subscription = await socket.receive({
  topic: "tasks.changed",
  onMessage: (message) => {
    console.log(message.data.taskId, message.data.status);
  },
});

const result = await socket.invoke({
  service: "tasks",
  action: "create",
  payload: { title: "Ship the next feature" },
});

const publication = await socket.send({
  topic: "tasks.changed",
  data: { taskId: "task-123", status: "done" },
});

if (subscription.isOk) {
  await subscription.value.unsubscribe();
}
socket.close();

Keep the client open for as long as your application needs live updates. The connection is lazy, subscriptions rejoin after reconnecting, and disconnected writes are not buffered or retried automatically. Topic names, data and any required scope are checked from the supplied types; Nile validates them and enforces policies on the backend. The server can expose HTTP and sockets together. See WebSockets for server setup.

Uploads

const result = await nile.upload({
  service: "documents",
  action: "upload",
  files: { document: file },
  fields: { title: "Invoice" },
  fetchOptions: { timeout: 60000 },
});

Multipart calls share the same cancellation, deadline and Result behavior as JSON calls. Content-Type is set by the runtime so the multipart boundary is correct.

Compatibility

Version 1.0.1 supports Nile 1.0.3 and 1.0.4 while keeping the existing HTTP and socket client APIs. It fixes header merging, cancellation and timeout cleanup; it does not add fields to Nile’s wire contract.

License

MIT

版本与发布记录

@nilejs/client 共发布 5 个版本,首次发布于 2026/03/01;过去 12 个月发布了 5 个版本。

版本发布日期距今
1.0.1latest2026/11/021 天前
1.0.02026/10/249 天前
0.0.32026/04/196 个月前
0.0.22026/03/018 个月前
0.0.12026/03/018 个月前

关于 @nilejs/client 的常见问题

@nilejs/client 是什么?

用于Nile后端框架的独立、类型安全的客户端

如何安装 @nilejs/client?

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

@nilejs/client 支持 TypeScript 吗?

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

@nilejs/client 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@nilejs/client 可以商用吗?

@nilejs/client 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@nilejs/client 还在维护吗?

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