Bucket 节点.js SDK
节点.js, JavaScript/ TypeScript 客户端 Bucket.co (英语)。 。 。 .
Bucket 支持特性粘接、跟踪特性使用情况、收集特性反馈,以及 远程配置特性。 。 。 .
安装
使用您最喜欢的软件包管理器安装 :
标签 标签标题="npm"
npm i @bucketco/node-sdk
最终结果
标签标题="yarn"
yarn add @bucketco/node-sdk
最终结果
标签标题="bun"
bun add @bucketco/node-sdk
最终结果
标签标题="pnpm"
pnpm add @bucketco/node-sdk
最终结果
标签标题="deno"
deno add npm:@bucketco/node-sdk
最终结果 最终结果
其他辅助语言/框架载于 支持的语言 页 次.
你也可以这样 直接使用 HTTP API
基本用途
要开始,你需要 获得你的密钥 从 环境设置 在巴凯特.
[叹息] 密钥只用于服务器侧 SDK 。 密钥为用户提供了获取的能力 信息往往敏感,因此不应用于客户端应用程序.
Bucket 将自动通过各种环境变量加载设置(参见 配置 页:1.
- 查找您的开发环境的 Bucket 密钥 环境设置 在巴凯特.
- 设定
BUCKET_SECRET_KEY在你身边.env文件 - 创建一个
bucket.ts包含以下内容的文件 :
import { BucketClient } from "@bucketco/node-sdk";
// Create a new instance of the client with the secret key. Additional options
// are available, such as supplying a logger and other custom properties.
//
// We recommend that only one global instance of `client` should be created
// to avoid multiple round-trips to our servers.
export const bucketClient = new BucketClient();
// Initialize the client and begin fetching feature targeting definitions.
// You must call this method prior to any calls to `getFeatures()`,
// otherwise an empty object will be returned.
bucketClient.initialize().then({
console.log("Bucket initialized!")
})
一旦客户端被初始化,您就可以与 isEnabled
以显示该功能是否针对该用户/公司:
[大 若为
user.id或者说company.id没有给出,整个user或者说company对象被忽略.
// configure the client
const boundClient = bucketClient.bindClient({
user: {
id: "john_doe",
name: "John Doe",
email: "[email protected]",
avatar: "https://example.com/users/jdoe",
},
company: {
id: "acme_inc",
name: "Acme, Inc.",
avatar: "https://example.com/companies/acme",
},
});
// get the huddle feature using company, user and custom context to
// evaluate the targeting.
const { isEnabled, track, config } = boundClient.getFeature("huddle");
if (isEnabled) {
// this is your feature gated code ...
// send an event when the feature is used:
track();
if (config?.key === "zoom") {
// this code will run if a given remote configuration
// is set up.
}
// CAUTION: if you plan to use the event for automated feedback surveys
// call `flush` immediately after `track`. It can optionally be awaited
// to guarantee the sent happened.
boundClient.flush();
}
你也可以使用这个 getFeatures() 返回所有特性的映射方法:
// get the current features (uses company, user and custom context to
// evaluate the features).
const features = boundClient.getFeatures();
const bothEnabled =
features.huddle?.isEnabled && features.voiceHuddle?.isEnabled;
高性能定位
SDK在您呼叫时联系 Bucket 服务器 initialize()
并下载其设定目标的规则.
这些规则与您提供的用户/公司信息相匹配
改为 getFeatures() (或通过) bindClient(..).getFeatures()) (中文(简体) ). 这意味着
getFeatures() 呼叫不需要联系 Bucket 服务器一次
initialize() 已完成. BucketClient 将继续定期
从背景中的 Bucket 服务器下载目标规则.
批量操作
SDK自动分批操作如用户/公司更新和特性跟踪事件来尽量减少API的呼叫. 批量缓冲通过客户端选项可配置:
const client = new BucketClient({
batchOptions: {
maxSize: 100, // Maximum number of events to batch
intervalMs: 1000, // Flush interval in milliseconds
},
});
您可以随时手动冲洗批量缓冲器 :
await client.flush();
[TIP] 建议打电话
flush()在您的应用程序关闭之前, 以确保所有事件被发送 .
限制费率
SDK包括了对地物事件的自动速率限制来防止压倒API. 费率限制按特性键和上下文的独特组合适用。 速率限制窗口大小可配置 :
const client = new BucketClient({
rateLimiterOptions: {
windowSizeMs: 60000, // Rate limiting window size in milliseconds
},
});
特征定义
特征定义包括确定哪些特征应当启用以及哪些配置值应当适用于任何特定用户/公司所需的规则.
调用时自动获取特性定义 initialize()。 。 。 .
然后在背景中缓存和刷新.
也可以获得目前使用的特征定义:
import fs from "fs";
const client = new BucketClient();
const featureDefs = await client.getFeatureDefinitions();
// [{
// key: "huddle",
// description: "Live voice conversations with colleagues."
// flag: { ... }
// config: { ... }
// }]
像云花岗工人一样的边缘跑道
与 Cloudflare 工人使用 Bucket 节点SDK, 设置 node_compat 旗帜 在您的扳手文件中。 。 。 .
而不是使用 BucketClient,使用时 EdgeClient 并确保你打电话 ctx.waitUntil(bucket.flush()); 在从工作功能返回之前.
import { EdgeClient } from "@bucketco/node-sdk";
// set the BUCKET_SECRET_KEY environment variable or pass the secret key in the constructor
const bucket = new EdgeClient();
export default {
async fetch(request, _env, ctx): Promise<Response> {
// initialize the client and wait for it to complete
// if the client was initialized on a previous invocation, this is a no-op.
await bucket.initialize();
const features = bucket.getFeatures({
user: { id: "userId" },
company: { id: "companyId" },
});
// ensure all events are flushed and any requests to refresh the feature cache
// have completed after the response is sent
ctx.waitUntil(bucket.flush());
return new Response(
`Features for user ${userId} and company ${companyId}: ${JSON.stringify(features, null, 2)}`,
);
},
};
见 实例/云层工人 作为可部署的例子.
Bucket在您员工的记忆中保留了一套缓存的特性定义,它用来决定哪些特性可以打开哪个用户/公司.
SDK缓存在内存中具有快速性能的特性定义. 对新工人实例的第一个请求从 Bucket 的服务器中获取定义,而随后的请求则使用缓存. 缓存到期后,会在后台更新. ctx.waitUntil(bucket.flush()) 确保完成背景工作,因此反应时间不受影响。 这个背景工作可能会增加你的工人的墙上时钟时间,但它不会在Cloudflare等平台上大大地增加可计费的CPU时间.
处理错误
SDK的设计是优雅地失败,从不向呼叫者抛出例外. 相反,它记录错误并提供 倒置行为 :
-
特性评价失败数字 :
const { isEnabled } = client.getFeature("my-feature"); // If feature evaluation fails, isEnabled will be false -
网络错误数字 :
// Network errors during tracking are logged but don't affect your application const { track } = client.getFeature("my-feature"); if (isEnabled) { try { await track(); } catch (error) { // The SDK already logged this error // Your application can continue normally } } -
缺少上下文数字 :
// The SDK tracks missing context fields but continues operation const features = client.getFeatures({ user: { id: "user123" }, // Missing company context will be logged but won't cause errors }); -
离线模式数字 :
// In offline mode, the SDK uses feature overrides const client = new BucketClient({ offline: true, featureOverrides: () => ({ "my-feature": true, }), });
SDK 记录所有错误, 并有适当的重度级别 。 您可以自定义日志 :
const client = new BucketClient({
logger: {
debug: (msg) => console.debug(msg),
info: (msg) => console.info(msg),
warn: (msg) => console.warn(msg),
error: (msg, error) => {
console.error(msg, error);
// Send to your error tracking service
errorTracker.capture(error);
},
},
});
远程配置
远程配置是一种动态而灵活的配置应用程序外的特征行为的方法 — — 不需要重新配置它.
类似 isEnabled,每个特性都有 config 属性。 此配置由 Bucket 内部管理 .
它的管理方式类似于对特性的访问的管理方式, 而不是二进制 isEnabled 你可以拥有
向不同的用户/公司提供的多个配置值.
const features = bucketClient.getFeatures();
// {
// huddle: {
// isEnabled: true,
// targetingVersion: 42,
// config: {
// key: "gpt-3.5",
// payload: { maxTokens: 10000, model: "gpt-3.5-beta1" }
// }
// }
// }
key 用于配置,但如果一个特性没有配置或没有配置值与上下文相匹配,则 key 将会是 undefined。在试图在应用程序中使用配置时,请检查此大小写. payload 是任意配置需要的可选 JSON 值.
碞钩 isEnabled,访问 config 在返回的对象上 getFeatures 不自动
生成一个 check 事件,与 config 返回对象上的财产 getFeature。 。 。 .
配置
弹匣 Node.js SDK可以通过环境变量配置,
磁盘上的配置文件或将选项传递到 BucketClient
建筑师。 默认情况下, SDK 搜索 bucketConfig.json 输入
当前工作目录.
| 选项 | 类型 | 说明 | 信封瓦尔 |
|---|---|---|---|
secretKey | 字符串 | 用于与 Bucket 服务器进行认证的秘密密钥. | (笑) |
logLevel | 字符串 | SDK的日志级别(例如, "DEBUG", (中文(简体) ), "INFO", (中文(简体) ), "WARN", (中文(简体) ), "ERROR") (中文(简体) ). 默认 : INFO | 贝克特语 LOGEVEL |
offline | 布尔 | 运行于离线模式 。 默认 : false,除非在测试中默认为 true 基于 TEST (原始内容存档于2017-03-21). env. var. | 烟花线 |
apiBaseUrl | 字符串 | Bucket 服务器的基础 API URL. | BUKET API BASE URL (英语) |
featureOverrides | 记录<字符串,布尔> | 为测试或本地开发指定特性覆盖的对象 。 见 实例/表达/应用 用于如何使用 featureOverrides 在测试. | (原始内容存档于2017-10-21) (英语). BUCKET FEATERS ENABLED, BUCKET FEATERS DIFFERENT |
configFile | 字符串 | 从磁盘上装入此配置文件 。 默认 : bucketConfig.json | BKKET CONFIG 文件夹 |
[!注]
BUCKET_FEATURES_ENABLED财务报告和审定财务报表BUCKET_FEATURES_DISABLED是分别启用或禁用的一些特性的逗号分隔列表.
bucketConfig.json 示例:
{
"secretKey": "...",
"logLevel": "warn",
"offline": true,
"apiBaseUrl": "https://proxy.slick-demo.com",
"featureOverrides": {
"huddles": true,
"voiceChat": { "isEnabled": false },
"aiAssist": {
"isEnabled": true,
"config": {
"key": "gpt-4.0",
"payload": {
"maxTokens": 50000
}
}
}
}
}
当使用一个 bucketConfig.json 地方发展,确保您加入到您的
.gitignore 文档。 您也可以在 BucketClient
建筑师。 配置选项的优先级如下,列于
重要顺序:
- 选项直接传递给建筑师,
- 环境变量,
- 配置文件 .
类型安全特征标记
要获得类型选中的特性标记, 请安装 Bucket CLI :
npm i --save-dev @bucketco/cli
然后生成类型 :
npx bucket features types
这将生成一个 bucket.d.ts 包含你的所有特征.
现在将对照 Bucket 中存在的特性检查任何特性的上调 .
以下是一个失败类型检查的例子:
import { BucketClient } from "@bucketco/node-sdk";
export const bucketClient = new BucketClient();
bucketClient.initialize().then(() => {
console.log("Bucket initialized!");
// TypeScript will catch this error: "invalid-feature" doesn't exist
bucketClient.getFeature("invalid-feature");
const {
isEnabled,
config: { payload },
} = bucketClient.getFeature("create-todos");
});

这是配置有效载荷检查失败的例子:
bucketClient.initialize().then(() => {
// TypeScript will catch this error as well: "minLength" is not part of the payload.
if (isEnabled && todo.length > config.payload.minLength) {
// ...
}
});

测试
当写出包含有特征标记的代码的测试时,你可以在程序上切换功能来测试不同的行为.
bucket.ts数字 :
import { BucketClient } from "@bucketco/node-sdk";
export const bucket = new BucketClient();
app.test.ts数字 :
import { bucket } from "./bucket.ts";
beforeAll(async () => await bucket.initialize());
afterEach(() => {
bucket.clearFeatureOverrides();
});
describe("API Tests", () => {
it("should return 200 for the root endpoint", async () => {
bucket.featureOverrides = {
"show-todo": true,
};
const response = await request(app).get("/");
expect(response.status).toBe(200);
expect(response.body).toEqual({ message: "Ready to manage some TODOs!" });
});
});
详见下节的功能覆盖.
特性覆盖
特性覆盖允许您在本地覆盖特性标记及其配置 。 这对发展和试验特别有用。 您可以以三种方式指定覆盖:
- 通过环境变量:
BUCKET_FEATURES_ENABLED=feature1,feature2
BUCKET_FEATURES_DISABLED=feature3,feature4
- 穿过
bucketConfig.json数字 :
{
"featureOverrides": {
"delete-todos": {
"isEnabled": true,
"config": {
"key": "dev-config",
"payload": {
"requireConfirmation": true,
"maxDeletionsPerDay": 5
}
}
}
}
}
- 程序通过客户端选项:
你可以用简单的 Record<string, boolean> 或以造物者或以造物者的方式通过它 client.featureOverrides数字 :
// pass directly in the constructor
const client = new BucketClient({ featureOverrides: { myFeature: true } });
// or set on the client at a later time
client.featureOverrides = { myFeature: false };
// clear feature overrides. Same as setting to {}.
client.clearFeatureOverrides();
要获得动态覆盖,请使用一个会带上下文并返回布尔或有形状的对象的函数 {isEnabled, config}数字 :
import { BucketClient, Context } from "@bucketco/node-sdk";
const featureOverrides = (context: Context) => ({
"delete-todos": {
isEnabled: true,
config: {
key: "dev-config",
payload: {
requireConfirmation: true,
maxDeletionsPerDay: 5,
},
},
},
});
const client = new BucketClient({
featureOverrides,
});
远程特征评价
除了本地特性评价外,Bucket还支持使用存储上下文进行远程评价. 当您想要使用用户/公司属性来评价先前发送给 Bucket 的特性时,此功能是有用的 :
// First, update user and company attributes
await client.updateUser("user123", {
attributes: {
role: "admin",
subscription: "premium",
},
});
await client.updateCompany("company456", {
attributes: {
tier: "enterprise",
employees: 1000,
},
});
// Later, evaluate features remotely using stored context
const features = await client.getFeaturesRemote("company456", "user123");
// Or evaluate a single feature
const feature = await client.getFeatureRemote(
"create-todos",
"company456",
"user123",
);
// You can also provide additional context
const featuresWithContext = await client.getFeaturesRemote(
"company456",
"user123",
{
other: {
location: "US",
platform: "mobile",
},
},
);
在下列情况下,远程评价特别有用:
- 您想要使用存储在 Bucket 中的最新用户/公司属性
- 你不想通过所有上下文属性 与每个评价
- 您需要确保不同服务的特性评价一致
使用快递
Bucket Node.js SDK的通俗整合方式是通过快递的中件.
import bucket from "./bucket";
import express from "express";
import { BoundBucketClient } from "@bucketco/node-sdk";
// Augment the Express types to include a `boundBucketClient` property on the
// `res.locals` object.
// This will allow us to access the BucketClient instance in our route handlers
// without having to pass it around manually
declare global {
namespace Express {
interface Locals {
boundBucketClient: BoundBucketClient;
}
}
}
// Add express middleware
app.use((req, res, next) => {
// Extract the user and company IDs from the request
// You'll want to use a proper authentication and identification
// mechanism in a real-world application
const user = {
id: req.user?.id,
name: req.user?.name
email: req.user?.email
}
const company = {
id: req.user?.companyId
name: req.user?.companyName
}
// Create a new BoundBucketClient instance by calling the `bindClient`
// method on a `BucketClient` instance
// This will create a new instance that is bound to the user/company given.
const boundBucketClient = bucket.bindClient({ user, company });
// Store the BoundBucketClient instance in the `res.locals` object so we
// can access it in our route handlers
res.locals.boundBucketClient = boundBucketClient;
next();
});
// Now use res.locals.boundBucketClient in your handlers
app.get("/todos", async (_req, res) => {
const { track, isEnabled } = res.locals.bucketUser.getFeature("show-todos");
if (!isEnabled) {
res.status(403).send({"error": "feature inaccessible"})
return
}
...
}
见 实例/表达/应用 一个完整的例子.
保存上下文的远程旗帜评价
如果您在每次评估特征标记时不想提供上下文, 但是
您更希望使用您先前发送给 Bucket 的属性
(通过打电话) updateCompany 财务报告和审定财务报表 updateUser) 你可以打电话 getFeaturesRemote
(或 getFeatureRemote 提供公正 userId 财务报告和审定财务报表 companyId。 。 。 .
这些方法将调用 Bucket 的服务器, 特性旗将远程评估
使用存储属性.
// Update user and company attributes
client.updateUser("john_doe", {
attributes: {
name: "John O.",
role: "admin",
},
});
client.updateCompany("acme_inc", {
attributes: {
name: "Acme, Inc",
tier: "premium"
},
});
...
// This will evaluate feature flags with respecting the attributes sent previously
const features = await client.getFeaturesRemote("acme_inc", "john_doe");
[大 用户和公司属性更新是同步处理的,因此可能 从属性更新到可用之间的小延迟 用于评价.
选择退出跟踪
使用一些您不想要发送的案例 user, (中文(简体) ), company 财务报告和审定财务报表
track (原始内容存档于2017-09-21). matters to Bucket.co. 这些通常是你可以冒充
系统中的另一个用户,不想干扰数据
由巴克特收集.
要禁用跟踪, 请绑定客户端 bindClient() 内容如下:
// binds the client to a given user and company and set `enableTracking` to `false`.
const boundClient = client.bindClient({ user, company, enableTracking: false });
boundClient.track("some event"); // this will not actually send the event to Bucket.
// the following code will not update the `user` nor `company` in Bucket and will
// not send `track` events either.
const { isEnabled, track } = boundClient.getFeature("user-menu");
if (isEnabled) {
track();
}
另一种不使用绑定客户端而禁用跟踪的方法是呼叫 getFeature()
或者说 getFeatures() 通过供应 enableTracking: false 在提交给
这些职能.
[大 但请注意
track(), (中文(简体) ),updateCompany()或者说updateUser()输入BucketClient将仍然发送跟踪数据。 因此,总是建议使用bindClient()当使用此 SDK.
飞翔
BucketClient 采用分批技术,尽量减少发送到 Bucket的服务器.
默认情况下, SDK 自动订阅处理退出信号并尝试冲出
任何未决事件。 这种行为由 flushOnExit 选项:
const client = new BucketClient({
batchOptions: {
flushOnExit: false, // disable automatic flushing on exit
},
});
跟踪自定义事件并设置自定义属性
跟踪允许事件和更新 Bucket 中的用户/公司属性. 比如,如果客户改变计划, 你会希望巴克特知道这一点, 以便继续在 Bucket 界面中提供最新的目标信息.
以下例子显示如何注册新用户,将其与公司联系起来 最后更新他们的计划.
// registers the user with Bucket using the provided unique ID, and
// providing a set of custom attributes (can be anything)
client.updateUser("user_id", {
attributes: { longTimeUser: true, payingCustomer: false },
});
client.updateCompany("company_id", { userId: "user_id" });
// the user started a voice huddle
client.track("user_id", "huddle", { attributes: { voice: true } });
也可以通过绑定客户端以下列方式实现相同: 1
const boundClient = client.bindClient({
user: { id: "user_id", longTimeUser: true, payingCustomer: false },
company: { id: "company_id" },
});
boundClient.track("huddle", { attributes: { voice: true } });
一些属性被 Bucket 用于改进 UI, 并被推荐 以方便导航:
name-- 显示名称user编号 :company, (中文(简体) ),email- 用户的电子邮件,avatar-- 用于user编号 :company阿凡达形象.
属性不能被嵌入(多级),必须要么是字符串, 整数或布尔数.
管理 Last seen
默认 updateUser编号 :updateCompany 呼叫自动更新给定的
用户/公司 Last seen bucket 服务器上的属性.
您可以控制如果 Last seen 当事件通过设置发送时,应当更新
meta.active = false。这往往有用,如果您
拥有一份背景工作,通过一系列公司 只是更新他们的
属性,但不包括其活动.
示例
client.updateUser("john_doe", {
attributes: { name: "John O." },
meta: { active: true },
});
client.updateCompany("acme_inc", {
attributes: { name: "Acme, Inc" },
meta: { active: false },
});
bindClient() 更新 Bucket 服务器上的属性,但不自动
更新 Last seen。 。 。 .
无 PII
Bucket SDK不收集任何元数据,HTTP IP地址是 没有 状态 存储。 为了追踪个别用户,我们建议使用类似数据库的东西 ID作为用户ID,因为它是独一无二的,不包括任何PII(个人可识别) 资料)。 但是,如果您正在使用电子邮件地址作为用户ID,但更喜欢 不将任何 PII 发送到 Bucket, 您可以在发送前先将敏感数据散开 给巴克特:
import { sha256 } from 'crypto-hash';
client.updateUser({ userId: await sha256("john_doe"), ... });
字体
类型与库捆绑在一起,并在导入时自动曝光 通过软件包管理器.
许可证
MIT 许可证 版权(c)2025 Bucket Aps