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

@zelostech/partition

v0.2.8

Published

前端分区包,用于管理和处理多分区环境下的请求路由和配置管理。

Readme

@zelos/partition

前端分区包,用于管理和处理多分区环境下的请求路由和配置管理。

功能特点

  • 自动管理多分区环境的请求路由
  • 支持基于车辆的分区动态路由
  • 提供分区信息的缓存机制
  • 事件驱动的状态通知
  • 提供 React Hooks 简化状态管理

安装

npm install @zelos/partition --save
yarn add @zelos/partition
pnpm add @zelos/partition

快速开始

import { PartitionService } from '@zelos/partition';
import Axios from 'axios';
import zauth from '@zelos/oauth';

const baseURL = AdminConfig.getDerivedAppUrl('gateway');
const request = zauth
  .extend(Axios, {
    client_id: AdminConfig.authClientId,
    client_secret: AdminConfig.authClientSecret,
    redirect_uri: `${window.location.protocol}//${window.location.host}`,
    host: AdminConfig.getDerivedAppDomain('auth'),
  })
  .create({
    baseURL,
    timeout: 1000 * 60,
  });

// 初始化时注入`分区`和`车辆分区`的请求拦截器
PartitionService.getInstance({
  // 可选,默认分区
  defaultPartition: 'default-partition',
  // 必填,请求客户端
  requestClient: request,
}).initialize();

API 文档

PartitionService

静态方法

  • getInstance(config?: PartitionConfig): PartitionService

    • 获取 PartitionService 的单例实例
    • 首次调用时必须提供配置
  • destroy(): void

    • 销毁当前实例,清除所有缓存和拦截器

实例方法

  • initialize(): PartitionService

    • 初始化分区服务
    • 安装请求拦截器,使其生效
    • 注意: 此方法现在是同步的并返回 this
  • isInitialized(): boolean

    • 检查分区服务是否已初始化
  • getPartitionEnabledAsync(): Promise<boolean>

    • 异步获取当前分区是否启用
  • getPartitionEnabled(): boolean | null

    • 同步获取当前分区是否启用
  • getPartitionsAsync(): Promise<Partition[]>

    • 异步获取所有可用分区列表(包括默认分区)
    • 如果首次获取失败,会尝试从本地存储加载
  • getPartitions(): Partition[]

    • 同步获取已加载的分区列表
    • 如果分区尚未加载,返回空数组
  • setCurrentPartition(partitionCode: string | null | undefined): void

    • 设置当前活动分区
    • 会触发 partitionChangedfullPartitionChanged 事件
  • setCurrentPartitionByVehicle(vehicleName: string): Promise<string | null | undefined>

    • 根据车辆名称异步获取并设置当前分区
    • 会触发 partitionChangedfullPartitionChanged 事件
    • 返回设置的分区代码或 null/undefined
  • getCurrentPartition(): string | null | undefined

    • 同步获取当前活动分区的代码
  • getCurrentFullPartition(): Partition | null | undefined

    • 同步获取当前活动分区的完整信息对象
  • getCurrentFullPartitionAsync(): Promise<Partition | null>

    • 异步获取当前活动分区的完整信息对象
  • getPartitionByVehicle(vehicleName: string, cancelToken?: CancelToken): Promise<Partition | null>

    • 根据车辆名称异步获取对应的分区信息(不设置当前分区)
    • 内部使用缓存,可通过 clearVehiclePartitionCache 清除
  • clearVehiclePartitionCache(vehicleName?: string): void

    • 清除车辆分区缓存
    • 如果不提供车辆名称,则清除所有缓存
  • getConfig(): PartitionConfig

    • 获取当前实例的配置信息
  • initPartitions(defaultFirstPartition?: boolean): Promise<Partition[]>

    • 手动触发分区列表的初始化加载
    • defaultFirstPartition: 是否将返回列表中的第一个分区设为默认当前分区
  • getCurrentError(): unknown | null | undefined

    • 获取服务初始化或运行过程中捕获的最后一个错误

事件

服务会触发以下事件,可以使用 on, once, off 方法监听:

| 事件名称 | 回调参数 | 描述 | | --- | --- | --- | | initialized | 无 | 服务初始化完成时触发 | | error | (error: unknown) | 发生错误时触发 | | enabledChanged | (enabled: boolean) | 分区是否启用状态变更时触发 | | partitionsLoaded | (partitions: Partition[]) | 分区列表加载完成时触发 | | partitionChanged | (partitionCode: string | null | undefined) | 当前分区代码变更时触发 | | fullPartitionChanged | (fullPartition: Partition | null | undefined) | 当前完整分区信息对象变更时触发 |

示例:

partitionService.on('partitionChanged', (partitionCode) => {
  console.log('当前分区代码已更改为:', partitionCode);
});

partitionService.on('fullPartitionChanged', (fullPartition) => {
  console.log('当前完整分区信息已更改为:', fullPartition);
});

类型定义

interface PartitionConfig {
  defaultPartition?: string | null | undefined; // 默认分区代码,可以是 null 或 undefined
  requestClient: AxiosInstance; // 必须提供 Axios 实例
  skipPartitionRules?: Array<(config: InternalAxiosRequestConfig) => boolean>; // 可选的跳过规则
}

interface Partition {
  code: string;
  name: string;
  gatewayHost: string;
  mqttHost: string;
}

// 事件接口
interface PartitionServiceEvents {
  initialized: () => void;
  enabledChanged: (enabled: boolean) => void;
  error: (error: unknown) => void;
  partitionsLoaded: (partitions: Partition[]) => void;
  partitionChanged: (partitionCode: string | null | undefined) => void;
  fullPartitionChanged: (fullPartition: Partition | null | undefined) => void;
}

React Hooks

为了方便在 React 应用中使用分区状态,包提供了以下 Hooks:

  • usePartitionEnabled(): boolean | null

    • 获取当前分区是否启用。
    • 当分区启用状态变化时,组件会自动重新渲染。
  • useCurrentPartition(): [string | null | undefined, (partition: string) => void]

    • 获取当前分区代码,并提供一个设置当前分区的函数。
    • 当分区变化时,组件会自动重新渲染。
  • useCurrentFullPartition(): Partition | null | undefined

    • 获取当前完整的 Partition 对象。
    • 当分区变化时,组件会自动重新渲染。
  • usePartitions(): Partition[]

    • 获取当前已加载的所有分区列表。
    • 当分区列表加载完成时,组件会自动重新渲染。
  • useCurrentError(): unknown | null | undefined

    • 获取 PartitionService 实例当前的错误状态。
    • error 事件触发时,组件会自动重新渲染。

示例:

import { useCurrentPartition, usePartitions } from '@zelos/partition';

function PartitionSelector() {
  const [currentPartition, setCurrentPartition] = useCurrentPartition();
  const partitions = usePartitions();

  const handleChange = (event) => {
    setCurrentPartition(event.target.value);
  };

  return (
    <select value={currentPartition ?? ''} onChange={handleChange}>
      {partitions.map((p) => (
        <option key={p.code} value={p.code}>
          {p.name}
        </option>
      ))}
    </select>
  );
}

注意事项

  1. 使用前必须先调用 initialize() 方法,该方法是同步的。
  2. 服务使用单例模式,多次调用 getInstance() 返回相同实例。
  3. 请求拦截器会自动处理分区路由,无需手动设置 Header (除非需要单次请求覆盖)。
  4. 车辆分区信息会被缓存,如需刷新请调用 clearVehiclePartitionCache()
  5. React Hooks 依赖于 PartitionService 的实例,请确保在使用 Hooks 前已调用 getInstanceinitialize

示例

单请求根据车辆分区切换

优先级最高,会自动路由到对应分区

// 发送请求时在 headers 中包含 X-Partition-Vehicle 头,服务会自动路由到对应分区
const response = await axios.get('/api/endpoint', {
  headers: {
    'X-Partition-Vehicle': 'ZL00004',
  },
});

单请求分区切换

// 发送请求时在 headers 中包含 X-Partition-Code 头,服务会自动路由到对应分区
const response = await axios.get('/api/endpoint', {
  headers: {
    'X-Partition-Code': 'partition-2',
  },
});

单请求跳过分区切换

// 发送请求时在 headers 中包含 X-Partition-Skip 头,服务会跳过分区路由
const response = await axios.get('/api/endpoint', {
  headers: {
    'X-Partition-Skip': 'true',
  },
});

全局分区切换

// 切换当前分区
partitionService.setCurrentPartition('partition-2');

// 根据车辆切换全局分区
partitionService.setCurrentPartitionByVehicle('ZL00004');

切换完成,所有的请求(除掉要跳过的),都会根据当前分区进行路由

自定义跳过分区规则

// 初始化 PartitionService 时可以这样配置
PartitionService.getInstance({
  requestClient: axios,
  skipPartitionRules: [
    // 跳过所有 GET 请求
    (config) => config.method === 'get',
    // 跳过特定 URL
    (config) => config.url?.startsWith('/api/public'),
    // 跳过带有特定 header 的请求
    (config) => Boolean(config.headers?.['skip-partition']),
  ],
}).initialize();

websocket 分区切换

import { useCurrentFullPartition } from '@zelos/partition';
import { useMemo, useEffect } from 'react';

function useWebSocket(url: string) {
  const partition = useCurrentFullPartition();

  const partitionUrl = useMemo(() => {
    if (!partition?.gatewayHost) {
      return url;
    }
    if (!url) {
      return null;
    }
    const urlObj = new URL(url);
    urlObj.host = partition.gatewayHost;
    return urlObj.toString();
  }, [partition?.gatewayHost, url]);

  useEffect(() => {
    if (!partitionUrl) {
      return;
    }
    const ws = new WebSocket(partitionUrl);

    // ....

    return () => {
      ws.close();
    };
  }, [partitionUrl]);
}

特别提示

该包请求使用的是传进来的 requestClient 实例,如果对 response 有特殊处理,可能会造成报错。所以特殊处理 response 时,请根据 X-Partition-Request 跳过处理逻辑,不要破坏原有 response 结构。例如:

import { PARTITION_REQUEST_HEADER } from '@zelos/partition';

request.interceptors.response.use(function (response) {
  const { headers = {} } = response.config;
  // 如果请求头中包含 X-Partition-Request 头,则跳过处理逻辑
  if (headers[PARTITION_REQUEST_HEADER] === 'true') {
    return response;
  }

  // 否则按照原有逻辑处理
  // ....
});