@epilot/feature-flags

中文文档
0.7.0发布于 2026/09/23UNLICENSEDTypeScriptCommonJS近 30 天下载 9154

后端功能旗+产品分析客户端用于epilot Node服务. 后霍格被盖下,表面为OpenFeature.

中文使用文档
文档目录16 节
  1. 为什么
  2. 安装
  3. 快开始
  4. API 密码
  5. init(options)
  6. 旗帜评价
  7. 镜像标记
  8. 一个圆形的多面旗
  9. 分析
  10. 直接 OpenFeature 客户端
  11. 背景形状
  12. 环境范围界定
  13. 评价缓存
  14. 地方发展
  15. 释放
  16. 扩展到其他提供者

@ epilot/ feature- flags

后端功能旗+epilot Node服务的产品分析. 后霍格被盖下,表面为OpenFeature.

为什么

  • 所有电子驾驶服务的共同特性旗界面
  • OpenFeature抽象表示,如果我们互换供应商,呼叫站点就不会改变
  • 方便Lambda的默认flushAt: 1, (中文(简体) ), flushInterval: 0,请求超时)

安装

npm install @epilot/feature-flags posthog-node

posthog-node 是同级依赖。 检查 扩展到其他提供者 关于如何推广到其他提供者的更多信息.

需要18号节点.

快开始

import { capture, init, isFeatureEnabled, shutdown } from '@epilot/feature-flags';

export const handler = async (event) => {
  await init({
    posthog: {
      apiKey: process.env.POSTHOG_API_KEY,
      host: process.env.POSTHOG_HOST,
    },
    // env defaults to process.env.STAGE — pass an explicit value only to override
    // <provider>: {
    //   apiKey: process.env.<PROVIDER>_API_KEY,
    //   host: process.env.<PROVIDER>_HOST,
    // },
    logger: powertoolsLogger,
  });

  const ctx = { orgId: event.org, userId: event.user };

  if (await isFeatureEnabled('ai-spam-detection', ctx, false)) {
    capture({ event: 'spam_check_started', context: ctx, properties: { messageId: event.id } });
    // ...
  }

  await shutdown(); // flush analytics before Lambda freezes
};

init() 可以安全地同时拨打——第一次拨打电线给供应商,随后的拨打共享同样的飞行中的承诺.

API 密码

init(options)

type InitOptions = {
  posthog?: {
    apiKey: string;
    host?: string;
    flushAt?: number;                     // default: 1
    flushInterval?: number;               // default: 0
    requestTimeout?: number;              // default: 5000ms
    featureFlagsPollingInterval?: number; // default: 30s
    personalApiKey?: string;
  };
  env?: string;          // deployment stage — see "Environment scoping" below
  logger?: Logger;       // any object with debug/info/warn/error
  cacheTtlMs?: number;   // evaluation cache TTL — default: 60s, 0 disables
  bulkOrgEval?: boolean; // isOrgFeatureEnabled resolves via the org map — default: true
};

回返 true 当所配置的提供者注册并准备就绪时, false 如果未提供配置或初始化失败( 在这种情况下, 所有旗下 evals 都会回到默认状态 ) capture() 是一个不开放。 失败的输入可以清除缓存的许诺, 以便下一个呼叫者可以重试 .

旗帜评价

const ctx = { orgId, userId };

await isFeatureEnabled('flag-name', ctx, false);          // boolean
await getStringFlag('flag-name', ctx, 'default');         // multivariate variant
await getNumberFlag('flag-name', ctx, 0);                 // numeric payload
await getObjectFlag('flag-name', ctx, { tier: 'free' });  // object payload
打开元件的方法邮电
getBooleanValueisFeatureEnabled
getStringValuegetFeatureFlag (多变量变体)
getNumberValuegetFeatureFlagPayload
getObjectValuegetFeatureFlagPayload

大批对应人员坐在他们旁边——见 一个圆形的多面旗。 。 。 .

镜像标记

多数 epilot 后端旗帜瞄准 organization 仅分组 : env 组合属性,或 Org 百分比推出。 对于这些旗帜,用户不能 更改结果, 所以使用 org 范围检查 :

await isOrgFeatureEnabled('o365-outlook-connect', orgId, false);

这事关成本, 不只是人造工程学。 评价缓存按键 (kind, flagKey, orgId, distinctId) 财务报告和审定财务报表 distinctId 嵌入用户——如此传入 { orgId, userId } 创建一个缓存项(和一个可计费的) 后霍格请求) 每个用户 尽管答案对所有人来说都是一样的 他们。 在高流量的路径上,它将缓存分解到~0%的命中率. 由 Org 键入 单靠一个热容器,每个缓存窗口最多可提出一个请求.

继续使用 isFeatureEnabled 满分 { orgId, userId } 当旗帜有时 人员级别条件或用户推开的百分比.

isOrgFeatureEnabled 解决整个在线地图:每个请求一个答案 org-scoped key for that org, 之后在同一缓存窗口中读取从中出. Batching是普通人的行为,不是每个呼叫者必须达到的 为. 无法解决的地图是 无答复没有 无启用所以钥匙掉下来了 应自己要求而不是采取 defaultValue - 每一面旗帜都是真的 在其默认适用前进行评审。 过 bulkOrgEval: false 改为 init 改为 总是抓取每个密钥; 这只值得对一个服务读取一个 org 范围 需要较小反应的旗帜.

一个圆形的多面旗

Org-scoped的读取已经共享了一个完整的项目地图,所以一个扇出 isOrgFeatureEnabled 电话不要求每个电话。 当呼叫者想要地图时 联系这两个人 本身——已知的密钥集,或每个旗帜:

// Known keys — always a full map, never null:
const flags = await areOrgFeaturesEnabled(['portals-engagement-center', 'portals-mcp'], orgId);
if (flags['portals-mcp']) { /* ... */ }

// Or the whole project's flags, when the set isn't known up front:
const all = await getOrgFeatureFlags(orgId);
if (all?.['portals-engagement-center']) { /* ... */ }

两个都花费了一个请求。 偏爱 areOrgFeaturesEnabled: 它充满 defaultValue 用于任何旗帜 无法解决的项目,所以没有 null 守卫 使用 getOrgFeatureFlags 当呼叫者需要每一面旗帜, 或者需要告诉 未解决 除 已禁用 (登入,说.

两种份额 一个 缓存条目 per org —— 全项目映射. 缩小请求范围 请求的密钥会按请求的一组键键取缓存,将它分解到每个呼叫站点并计算成本 a 请求每个。 因为他们分享它, 任何后期的角镜 isOrgFeatureEnabled 在同一个进程中 免费读取该条目的答案,包括在不相关请求路径上的旗帜.

霍格邮局收费 /flags 电话和 项目中活动旗帜的数量不影响每项请求的成本, (中文(简体) ), 这就是为什么一个地图比N键便宜 和为什么Org-scoped getter把它。 (本节) 当地评价的定义民意测验(一个终点)适用10项要求的逐名乘数 此软件包不使用。 ) 大通电话的确要花费更多的响应大小和缓存 内存,因为一个条目持有每个项目旗而不是一个布尔.

回返 null 当没有PostHog供应商注册或请求无法使用时 映射 – 然后应用您自己的每面旗默认值, 并注意一个密钥从一个 无null 地图是工程没有的旗帜 。 多变量旗帜倒塌到 true 当变量匹配; 读取变量和有效载荷 getStringFlag 编号 : getObjectFlag。 。 。 .

分析

capture({
  event: 'message_sent',
  context: { orgId, userId },
  properties: { channel: 'email', size: 1024 },
});

await shutdown(); // flushes pending events

capture() 通过 OpenFeature 的路由 track() 和活动的提供者,所以在没有提供者配置时,它是不开放的.

直接 OpenFeature 客户端

import { getFeatureFlagsClient } from '@epilot/feature-flags';

const client = getFeatureFlagsClient();
const details = await client.getBooleanDetails('flag', false, { targetingKey: 'org_user' });

logger.debug(details.reason); // 'TARGETING_MATCH' | 'DEFAULT' | 'ERROR' | ...

背景形状

type EpilotFlagContext = {
  orgId?: string;
  userId?: string;
};

翻译为:

  • distinctId = ${orgId}_${userId}
  • groups = { organization: orgId } 用于 org 升起旗帜

您也可以通过一个原始的 OpenFeature EvaluationContext 直接进行控制.

环境范围界定

软件包读取 process.env.STAGE 自动发送 groupProperties: { organization: { env } } 在每一旗的评价。 每一个电子驾驶Lambda服务 STAGE 设置,所以你不需要通过手动连接.

这符合现有的 epilot PostHog 旗使用的常规——多个放出组,每个放出组由 env 组属性——因此向dev推出的旗帜不会意外地与prod相匹配,反之亦然.

// default behavior — STAGE picked up from env
await init({ posthog: { ... } });

// override only when you need to (e.g. tests, multi-tenant service)
await init({ posthog: { ... }, env: 'preview-42' });

capture() 事件得到 env 也作为常规事件财产.

评价缓存

每一个未标记的旗帜评价都是可收费的 PostHog 请求——postHog-node 没有自己的结果缓存(没有) personalApiKey 每个电话都是网络 /decide编号 :/flags 请求,而其唯一的内部缓存 $feature_flag_called 分析事件,而不是请求). 因此,供应商对每个评价结果进行缓存 (kind, flagKey, orgId, distinctId) 默认为60个,以每个进程1,000个条目为限.

  • 缓存漏掉的费用恰恰是本来会提出的一个请求;冷的容器从未比没有缓存更糟糕.
  • 在TTL内用热容器传播旗帜变化;冷容器立即看到它们.
  • 失败的评价缓存了 TTL 的倒置默认值, 当 PostHog 无法到达时, TTL 作为后压值加倍 .
  • 通过电路或禁用 init({ cacheTtlMs }) (单位:千美元)0 / 禁用).
  • 散装分辨率在每条条目下缓存整个地图 (orgId, distinctId),而当同一上下文被缓存时,单旗布尔检查会读取该条目。 块状扫描结果从不回答人状扫描:块状键嵌入相同的 distinctId上下文改变。 地图所持有的密钥不归结于请求,而不是解决 false与每个旗手不同 没有 缓存失败, 因为一个缓存失败会让 TTL 的默认标记 .

包裹从不调用 posthog.groupIdentify()。旗帜瞄准仅需要 groups + 键 groupProperties 每一个容器都是新鲜的,所以用容器来识别体积表 $groupidentify 活动)。 坚持下去 env 在 org 组配置文件上——所以 org 可以通过 env 在PostHog UI中——被处理出带外(例如一次性回填脚本或在org创建时间),而不是从请求路径.

若为 process.env.STAGE 没有设定,也没有明确 env 通过, 包跳过 groupProperties 完全没有.

地方发展

npm install
npm run lint    # tsc --noEmit
npm test        # vitest
npm run build   # emit dist/

释放

标记承诺 :

npm version patch   # or minor / major
git push --follow-tags

CI 在任何标签匹配上发布到 npm v*。 。 。 .

扩展到其他提供者

要将这个软件包扩展至与其他提供者合作,您可以创建一个自定义提供者,执行OpenFeature提供者接口. 提供者应能够处理国旗评价和分析捕获.

所以,如果你最后使用一个特定于你的使用大小写 PostHog 的内存或内部FF 替代品,这个软件包只是给你一个接口来配合它. 你唯一要做的就是执行提供者接口,然后传给 init 函数.

版本与发布记录

@epilot/feature-flags 共发布 13 个版本,首次发布于 2026/05/01;过去 12 个月发布了 13 个版本。

版本发布日期距今
0.7.0latest2026/09/231 个月前
0.6.02026/09/022 个月前
0.5.22026/07/084 个月前
0.5.12026/07/084 个月前
0.5.02026/07/084 个月前
0.4.12026/07/034 个月前

关于 @epilot/feature-flags 的常见问题

@epilot/feature-flags 是什么?

后端功能旗+产品分析客户端用于epilot Node服务. 后霍格被盖下,表面为OpenFeature.

如何安装 @epilot/feature-flags?

在项目目录运行 npm install @epilot/feature-flags,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:posthog-node(^4.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@epilot/feature-flags 支持 TypeScript 吗?

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

@epilot/feature-flags 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@epilot/feature-flags 需要什么版本的 Node.js?

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

@epilot/feature-flags 可以商用吗?

@epilot/feature-flags 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@epilot/feature-flags 的下载量有多少?

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

@epilot/feature-flags 还在维护吗?

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